3

I'd like to create a new class that inherits two subclasses of QWidget. I know multi-inheritance isn't possible in pyqt, but how could I manage to have the properties of both parent classes in one subclass?

What I wish I could do is as follows:

class A(QWidget):

    def __init__(self, widget, parent=None):
        widget.destroyed.connect(self.destroy_handler)

    @pyqtSlot()
    def destroy_handler(self):
        pass

class B (A, QStatusBar):
    def __init__(self, widget, parent=None):
        A.__init__(self, widget)
        QStatusBar.__init__(self, parent)

    @pyqtSlot()
    def destroyed_handler(self):
        print("Destroyed")
Spirine
  • 1,837
  • 1
  • 16
  • 28

1 Answers1

7

I finally found how to do it: first of all, the problems came from A and QStatusBar inheriting QWidget. We can't change QStatusBar, so we must changer A. A shouldn't inherit QWidget: so let's create another class, AInterface, like that:

class AInterface(QObject):
    def __init__(self, a, parent=None)
        super().__init__(parent=parent)
        self.a = a
        self.connect_signal()

    def connect_signal(self, widget):
        widget.destroyed.connect(self.handler)

    @pyqtSlot()
    def handler(self):
        self.a.handler()

A has now the following implementation:

class A:
    def __init__(self, widget):
        a.widget = widget
        a.interface = AInterface(self)

    def handler(self):
        pass

Thus, now we can create subclasses inheriting not only A but also any QObject, like this:

class B(QStatusBar, A):
    def __init__(self, widget, parent=None):
        QStatusBar.__init__(self, parent=parent, wiget=widget)
        A.__init__(self, widget)

    def handler(self):
        self.show('Destroyed', 3000)

Notice the widget=widget in the constructor of QStatusBar: if we don't specify it, a TypeError is thrown...

Spirine
  • 1,837
  • 1
  • 16
  • 28
  • I have a slightly different case and it looks like some issue with QtObjects swallowing arguments of all sibling classes when using multiple inheritance. EDIT: this seems to be intended: http://pyqt.sourceforge.net/Docs/PyQt5/multiinheritance.html – krassowski Oct 10 '17 at 11:16
  • Ran into this as well. I was extending a basic widget: `class SpecialLabel(QLabel, OtherClass)` and kept getting errors for missing arguments. Turns out that `QLabel` tried to call the constructor for `OtherClass`. Fixed it by going along with it and naming the arguments. In `SpecialLabel.__init__`: `super().__init__(other_arg=other_arg, *args, **kwargs)`. This called both QLabel.__init__ and OtherClass.__init__ correctly. – Roberto Oct 08 '20 at 14:12