2013-12-09 23 views
5

Pyside oluşturulmuş bir python sınıfını miras alan bir iletişim sınıfım var ancak benim sorunum, başka bir temel sınıf ekleyerek genişletilememesi.PySide, PysideUIC ve Çoklu Kalıtım

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

Ben Worker ile MainDialog uzatmak çalıştığınızda süper çağırmaz Worker 'ın __init__ nedeniyle baskı dlg.data başarısız 'AttributeError: '

MainDialog veriler '' nesne hiçbir özelliğin var''

Çevremdeki tek çalışmam süper göz ardı ediyor ve her bir __init__'u manuel olarak çağırıyor.

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

Bu benim tek çözümüm mü?

Bu, Python 2.7 içindir.

+0

Deneyimlerim söz konusu olduğunda, 'super() 'PySide sarmalayıcıları Qt ile çalışmıyor ve PyQt'nin burada farklı olduğuna inanmıyorum. Yani '__init__'s el ile arama tek yol olabilir. Elmas şeklindeki miraslardan kaçınmayı (ya da etrafta doladığınızdan) emin olun. – quazgar

cevap

1

Pitonda birden fazla kalıtım zor olur. Mükemmel bir şekilde çalışmasını istiyorsanız, miras aldığınız sınıfların herhangi bir çatışması olamaz. Çoğu durumda, pyside ile birden fazla kalıtım çatışmaya neden olur, çünkü her şey QObject'i özdeş değişkenler ve yöntemler vererek miras alır. Python, hangisinin devralılacağını bilmiyor. Resim çatışma için başka bir alan. Dikkate alınması gereken diğer bir şey miras emridir. Python'un kalıtım ve init den soldan sağa doğru çalıştığına inanıyorum. Yani sadece QtGui.QDialog ve İşçi için init yöntemini (Ui_Dialog muhtemelen çakışacaktır) istiyorsanız, denemek isteyebilirsiniz.

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

Piton 3'te süper yöntemi biraz farklı olarak arayabilirsiniz.

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

Init'i 2.7 için çağırmanın yolunun, işleri yapmanın doğru yolu olduğuna inanıyorum. Buna benzer sorular her yerdedir. Bu, Diamond problem olarak bilinen yaygın bir sorundur. Python super method and calling alternatives, bazı şeyleri biraz daha açıklayabilir.

+0

Ancak 'super() ', yalnızca ataların/yapımcıların yapıcılarını uygun şekilde uygularsa (** anahtar sözcükleri kabul etmek ve bir sonraki" süper() "iletmek gibi) duyurulduğu şekilde çalışır.Bu Qt sınıflarının PySide sarmalayıcıları için geçerli gibi görünmüyor. – quazgar

1

Worker birinci taban sınıf olun: İlk çağrılan

class MainDialog(Worker, QtGui.QDialog, Ui_Dialog) 

Bu hala MainDialog.__init__ sonuçlanacaktır, ardından Worker.__init__ (bazı baskı ifadeleri eklerseniz görebilirsiniz). Ancak, içinden data özniteliğine erişebileceksiniz. o object devralan sadece sıradan bir piton sınıftır ve her zamankinden super çağırmaz çünkü

Ui_Dialog sınıf gerçekten bu hiçbirinde rakam değildir. Böylece, baz sınıf düzeninde istediğin yere gidebilirsin.

Açıkçası, eğer bu şekilde şeyler yaparsanız, Worker sınıfındaki diğer temel sınıflardan herhangi bir yöntem kullanmamaya dikkat etmelisiniz - ancak zaten zaten bu "problem" e sahiptiniz (sadece farklı bir sırada)).