PySide Multiple Inheritance: Inheriting a QWidget

2019-08-05 09:23发布

问题:

I'm trying to create a set of PySide classes that inherit QWidget, QMainWindow, and QDialog. Also, I would like to inherit another class to overrides a few functions, and also set the layout of the widget.

Example:

Mixin:

class Mixin(object):
    def __init__(self, parent, arg):
        self.arg = arg
        self.parent = parent

        # Setup the UI from QDesigner
        ui = Ui_widget()
        ui.setupUi(self.parent)

    def setLayout(self, layout, title):
        self.parent.setWindowTitle(title)
        self.parent.setLayout(layout)

    def doSomething(self):
        # Do something awesome.
        pass

Widget:

class Widget(Mixin, QtGui.QWidget):
    def __init__(self, parent, arg):
        super(Widget, self).__init__(parent=parent, arg=arg)

This won't work, but doing this through composition works

Widget (Composition):

class Widget(QtGui.QWidget):
    def __init__(self, parent, arg):
        super(Widget, self).__init__(parent=parent)
        mixin = Mixin(parent=self, arg=arg)

        self.setLayout = mixin.setLayout
        self.doSomething = mixin.doSomething

I would like to try to have the widget inherit everything instead of having part of it done through composition. Thanks!

回答1:

Keep class Widget(Mixin, QtGui.Widget):, but add a super call in Mixin.__init__. This should ensure the __init__ method of both Mixin and QWidget are called, and that the Mixin implementation of the setLayout method is found first in the MRO for Widget.

class Mixin(object):
    def __init__(self, parent=None, arg=None):
        super(Mixin, self).__init__(parent=parent)  # This will call QWidget.__init__
        self.arg = arg
        self.parent = parent

        # Setup the UI from QDesigner
        ui = Ui_widget()
        ui.setupUi(self.parent)

    def setLayout(self, layout, title):
        self.parent.setWindowTitle(title)
        self.parent.setLayout(layout)

    def doSomething(self):
        # Do something awesome.
        pass


class Widget(Mixin, QtGui.QWidget):
    def __init__(self, parent, arg):
        super(Widget, self).__init__(parent=parent, arg=arg)  # Calls Mixin.__init__