1

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!

ScottWilson
  • 360
  • 3
  • 15
  • 1
    By not working, do you mean the `__init__` in the `Mixin` class not being called? If so, [this might be related](http://stackoverflow.com/questions/6098970/are-mixin-class-init-functions-not-automatically-called-in-python?rq=1) – metatoaster Aug 18 '14 at 22:37
  • I did try that. Either I was getting cases where one of the __init__ in the Mixin or QWidget class weren't being called (I can't remember which. I don't think Python specified), or Python was using the QWidget setLayout. – ScottWilson Aug 18 '14 at 22:49

1 Answers1

3

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__
dano
  • 91,354
  • 19
  • 222
  • 219
  • I tried that, and I get the following error: super(type, obj): obj must be an instance or subtype of type – ScottWilson Aug 18 '14 at 23:12
  • I tried (almost) this exact code and it worked ok...Can you provide a complete traceback? – dano Aug 18 '14 at 23:17
  • I'm doing this in Maya 2015, so the traceback is a little less than useful. The only other information it gives me is that it is a TypeError, and the path to the module that failed. – ScottWilson Aug 18 '14 at 23:19
  • Are you sure you put the right class name in both calls to `super`? That's the only reason I can think of for that error to appear. – dano Aug 18 '14 at 23:20
  • Yup, both calls to super use the right class names. – ScottWilson Aug 18 '14 at 23:21
  • @ScottWilson Hmm, unfortunately I really can't say what the issue is without a traceback. I just know that running this code in isolation works ok (for me, at least). Is it possible for you to run this code outside of Maya to see if you still get an error? – dano Aug 18 '14 at 23:23