Triple inheritance causes metaclass conflict... Sometimes

Viewed 16405

Looks like I stumbled upon a metaclass hell even when I didn't wanted anything to do with it.

I'm writing an app in Qt4 using PySide. I want to separate event-driven part from UI definition, which is generated from Qt Designer files. Hence I create a "controller" classes, but to ease my life I multiple-inherit them anyways. An example:

class BaseController(QObject):
    def setupEvents(self, parent):
        self.window = parent

class MainController(BaseController):
    pass

class MainWindow(QMainWindow, Ui_MainWindow, MainController):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.setupUi(self)
        self.setupEvents(self)

This works as expected. It also has inheritance from (QDialog, Ui_Dialog, BaseController). But when I subclass BaseController and try to inherit from said subclass (in place of BaseController), I receive an error:

TypeError: Error when calling the metaclass bases metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

Clarification: Both QMainWindow and QDialog inherit from QObject. BaseController must also inherit from it because of Qt event system peculiarities. Ui_ classes only inherit from simple Python object class. I searched for solutions, but all of them involve cases of intentionally using metaclasses. So I must be doing something terribly wrong.

EDIT: My description may be clearer by adding graphs.

Working example:

QObject
|      \___________________
|            object        |
QMainWindow     |          BaseController
|      /---Ui_MainWindow   |
|      |                   MainController
MainWindow-----------------/

Another working example:

QObject
|      \___________________
|            object        |
QDialog         |          BaseController
|      /---Ui_OtherWindow  |
|      |                   |
OtherWindow----------------/

Not working example:

QObject
|      \___________________
|            object        |
QDialog         |          BaseController
|      /---Ui_OtherWindow  |
|      |                   OtherController
OtherWindow----------------/
2 Answers
Related