Multiply inherit from QWidget and another base cla

2019-08-24 18:24发布

问题:

I am trying to create a PyQt5.QtWidgets.QWidget derived widget, whilst at the same time inherit from another base class, Base.

Inheriting from Base causes an error when calling the QWidget constructor, saying I never provided the arguments which Base requires.

This is how I attempt to call the QWidget and Base constructors:

class Deriv(QtWidgets.QWidget, Base):
    def __init__(self):
        QtWidgets.QWidget.__init__(self)
        Base.__init__(self, "hello world")

The error I'm getting says:

    QtWidgets.QWidget.__init__(self)
TypeError: __init__() missing 1 required positional argument: 'id'

Is it possible to inherit from both QWidget and Base, and if so, how do I call their respective constructors correctly?

Here is an exemplar app which reproduces the error I am experiencing:

#!/usr/bin/env python3
import sys
from PyQt5 import QtWidgets

class Base(object):
    def __init__(self, id):
        self.id = id

class Deriv(QtWidgets.QWidget, Base):
    def __init__(self):
        QtWidgets.QWidget.__init__(self)
        Base.__init__(self, "hello world")

        self.show()

def main():
    app = QtWidgets.QApplication(sys.argv)
    d = Deriv()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

Here is the traceback:

Traceback (most recent call last):
  File "./test.py", line 22, in <module>
    main()
  File "./test.py", line 18, in main
    d = Deriv()
  File "./test.py", line 11, in __init__
    QtWidgets.QWidget.__init__(self)
TypeError: __init__() missing 1 required positional argument: 'id'

Note that if I only inherit from QWidget (so just remove everything referring to Base), then the code works

class Deriv(QtWidgets.QWidget):
    def __init__(self):
        QtWidgets.QWidget.__init__(self)

        self.show()

回答1:

I'm assuming QtWidgets.QWidget.__init__ itself uses super to call __init__. With your single inheritance case, the MRO consists of three classes: [Deriv, QtWidgets.QWidget, object]. The call super(QtWidgets.QWidget, self).__init__ would call object.__init__, which doesn't expect any additional arguments.

In your multiple inheritance example, the MRO looks like

[Deriv, QtWidgets.QWidget, Base, object]

which means now the call super(QtWidgets.QWidget, self).__init__ refers not to object.__init__, but Base.__init__, which does require an additional argument, leading to the error you see.