I have a dialog class that is inheriting a pyside-uic-generated python class but my problem is that it cannot be extended my adding another base class.
import sys
from PySide import QtGui
from mi_ui import Ui_Dialog
class Worker(object):
def __init__(self):
super(Worker, self).__init__()
self.data = 1
class MainDialog(QtGui.QDialog, Ui_Dialog, Worker):
def __init__(self):
super(MainDialog, self).__init__()
self.setupUi(self)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
dlg = MainDialog()
print dlg.data
dlg.show()
sys.exit(app.exec_())
When I try to extend MainDialog
with Worker
, super does not call the Worker
's __init__
and the print dlg.data fails because "AttributeError: 'MainDialog' object has no attribute 'data'"
My only work around seems to ignore super and invoke each __init__
manually.
QtGui.QDialog.__init__(self)
Worker.__init__(self)
Is this my only solution?
This is for Python 2.7.
Multiple inheritance is tricky in python. The classes that you are inheriting from cannot have any conflicts if you want it to work perfectly. In most cases multiple inheritance with pyside does cause a conflict because everything inherits QObject giving identical variables and methods. Python doesn't know which one to inherit. The painting is another area for conflict. The other thing to consider is the order of the inheritance. I believe that python tries inheritance and init from left to right. So if you only want the init method for the QtGui.QDialog and the Worker (Ui_Dialog will probably conflict) then you might want to try.
class MainDialog(QtGui.QDialog, Worker, Ui_Dialog):
In python 3 you can call the super method a little differently.
class MainDialog(QtGui.QDialog, Worker, Ui_Dialog):
super().__init__()
I believe that the way you are calling the init for 2.7 is the correct way of doing things. Questions similar to this are all over the place. It is a common problem known as the Diamond problem. Python super method and calling alternatives may explain things a little more.
Make Worker
the first base-class:
class MainDialog(Worker, QtGui.QDialog, Ui_Dialog)
This will still result in MainDialog.__init__
being called first, then Worker.__init__
(which can see if you add some print statements). But you will still be able to access the data
attribute from inside the MainDialog.__init__
.
The Ui_Dialog
class doesn't really figure in any of this, because it is just an ordinary python class inheriting from object
and doesn't ever call super
. So it can go anywhere you like in the base-class order.
Obviously, if you do things this way, you will have to take care not to clobber any methods from the other base-classes in the Worker
class - but you already had this "problem" anyway (just in a different order).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With