2013-12-09 3 views
5

Ich habe eine Dialogklasse, die eine pyside-uic-generierte Python-Klasse erbt, aber mein Problem ist, dass es nicht erweitert werden kann, indem ich eine andere Basisklasse hinzufüge.PySide, PysideUIC und multiple Vererbung

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_()) 

Wenn ich versuche, MainDialog mit Worker zu erweitern, super ruft nicht die Worker ‚s __init__ und der Druck dlg.data schlägt fehl, weil "Attribute: 'MainDialog 'data' Objekt keine Attribute hat'"

Meine einzige Arbeit herum scheint super zu ignorieren und jede __init__ manuell aufzurufen.

QtGui.QDialog.__init__(self) 
Worker.__init__(self) 

Ist das meine einzige Lösung?

Dies ist für Python 2.7.

+0

Soweit es meine Erfahrung betrifft, funktioniert 'super()' nicht mit den PySide Wrappern zu Qt, und ich glaube nicht, dass PyQt hier anders ist. Es kann also der einzige Weg sein, die "__init__'s manuell aufzurufen. Achten Sie darauf, rautenförmige Erbschaften zu vermeiden (oder zu umgehen). – quazgar

Antwort

1

Mehrfache Vererbung ist in Python schwierig. Die Klassen, von denen Sie erben, können keine Konflikte haben, wenn Sie möchten, dass sie perfekt funktionieren. In den meisten Fällen verursacht die Mehrfachvererbung mit pyside einen Konflikt, weil alles QObject erbt und identische Variablen und Methoden liefert. Python weiß nicht, welchen er erben soll. Das Gemälde ist ein weiterer Bereich für Konflikte. Die andere Sache ist die Reihenfolge der Vererbung. Ich glaube, dass Python Vererbung und Init von links nach rechts versucht. Wenn Sie also nur die init-Methode für den QtGui.QDialog und den Worker (Ui_Dialog wird wahrscheinlich einen Konflikt) wollen, dann sollten Sie es versuchen.

class MainDialog(QtGui.QDialog, Worker, Ui_Dialog): 

In Python 3 können Sie die Super-Methode ein wenig anders nennen.

Ich glaube, dass die Art, wie Sie die Init für 2.7 aufrufen, die richtige Art ist, Dinge zu tun. Ähnliche Fragen gibt es überall. Es ist ein bekanntes Problem, das als Diamond problem bekannt ist. Python super method and calling alternatives kann die Dinge ein wenig mehr erklären.

+0

Aber beachte, dass 'super()' nur wie angekündigt funktioniert, wenn die Vorfahren ihre Konstruktoren entsprechend implementieren (wie zum Beispiel '** keywords' akzeptieren und an das nächste' super() 'weiterleiten).Dies scheint für die PySide-Wrapper der Qt-Klassen nicht der Fall zu sein. – quazgar

1

Make Worker die erste Basis-Klasse:

class MainDialog(Worker, QtGui.QDialog, Ui_Dialog) 

Dies wird in MainDialog.__init__ führen nach wie vor zuerst genannt wird, dann Worker.__init__ (die sehen können, wenn Sie einige Druck Aussagen hinzufügen). Sie können jedoch weiterhin auf das data Attribut innerhalb der MainDialog.__init__ zugreifen.

Die Ui_Dialog Klasse ist Figur nicht wirklich in irgendetwas davon, weil es nur eine gewöhnliche Python-Klasse von object vererben ist und je super nicht nennen. So kann es in der Basisklasse beliebig platziert werden.

Offensichtlich, wenn Sie die Dinge auf diese Weise tun, müssen Sie darauf achten, keine Methoden von den anderen Basisklassen in der Klasse Worker zu überlisten - aber Sie hatten dieses "Problem" sowieso schon (nur in einer anderen Reihenfolge).