2012-09-05 8 views
9

Ich habe versucht, eine Operation (setParent) auf ein Objekt in Python (eine Instanz einer Klasse, die von einer anderen Klasse erbt - um genau zu sein, QtGui.QLabel), aber während der Laufzeit wurde der obige Fehler ausgelöst. Das Objekt selbst hatte einige Felder mit tatsächlichem Inhalt (verifiziert beim Debuggen), aber aus irgendeinem Grund konnte ich es nicht "benutzen". Was bedeutet der Fehler und wie kann ich ihn beheben? Für einige zusätzliche Informationen werde ich sagen, dass das Objekt von einer statischen Methode zurückgegeben wurde, bevor ich versuchte, diese Operation darauf auszuführen.Python: RuntimeError: Super-Klasse __init __() von% S wurde nie aufgerufen

Die Unterklasse hat eine __init__() eigene Funktion:

def __init__(self, image, father): 
     super(AtomicFactory.Image, self).__init__(father) 
     self.raw_attributes = image.attributes 
     self.attributes = {} 
     father.addChild(self) 
     self.update() 

Jetzt habe ich einen ähnlichen Code, einen einfachen, dass die gleichen Fehler auf der Linie widget.setParent(mw) hatte, wenn das Fenster verschoben wurde.

#!/usr/bin/env python 
import sys 
import copy 
from PyQt4 import QtCore, QtGui 

if __name__ == "__main__": 
    app = QtGui.QApplication(sys.argv) 
    main_widget=QtGui.QWidget() 
    widget = QtGui.QPushButton('Test') 
    widget.resize(640, 480) 
    widget.setParent(main_widget) 
    widget.move(0, 0) 
    widget2=QtGui.QPushButton('Test2') 
    widget2.i=0 
    widget2.resize(600, 200) 
    widget2.setParent(main_widget) 
    widget2.move(640, 0) 
    def onResize(event): 
     print event 
     mw=copy.deepcopy(main_widget) 
     widget.setParent(mw) 
     widget2.setParent(mw) 
     widget.move(0, 0) 
     widget2.move(640, 480) 
     main_widget_width=main_widget.width() 
     widget_width=widget.width() 
     width2=main_widget_width-widget_width 
     height2=widget2.height() 
     widget2.resize(width2, height2) 
     widget2.move(640, 0) 
    main_widget.resizeEvent=onResize 
    def onClick(): 
     size=(widget2.width(), widget2.height()) 
     if(widget2.i%2==0): 
      widget2.resize(int(size[0]/2), int(size[1]/2)) 
     else: 
      widget2.resize(size[0]*2, size[1]*2) 
     widget2.i+=1 
    QtCore.QObject.connect(widget, QtCore.SIGNAL('clicked()'), onClick) 
    main_widget.show() 
    sys.exit(app.exec_()) 

Was war das Problem?

+0

Wenn Ihre abgeleitete Klasse 'MyDerived' ein eigenes' __init__' hat, fügen Sie die Zeile 'super (MyDerived, self) .__ init __()' hinzu. – halex

+0

Es tut. Das Objekt wurde zuvor erstellt und wurde gut genutzt. Ich hätte setParent() auch problemlos in der Anfangsphase verwenden können. Sie wurde dann in eine Liste eingefügt und die oben beschriebene statische Methode "fand" sie in der Liste und gab sie dann an eine andere statische Methode zurück. Als letzterer versuchte, setParnet() zu verwenden, wurde der Fehler zurückgegeben. Wie auch immer, die __init __() benutzerdefinierte Funktion der Unterklasse ist: – Tomer

+0

def __init __ (selbst, Bild, Vater): Super (AtomicFactory.Image, selbst) .__ init __ (Vater) selb.raw_attributes = image.attributes self.attribute = {} vater.addChild (self) selb.update() – Tomer

Antwort

15

Wenn Sie QObject erben wollen (oder QWidget), müssen Sie immer rufen Sie die Super-Klasse __init__:

class MyObject(QObject): 
    def __init__(self, *args, **kwargs): 
     super(MyObject, self).__init__(arguments to parent class) 
     #other stuff here 

Sie können auch die __init__ die der Eltern nennen Klasse nach einigen Anweisungen, aber Sie können nicht nennen QObject Methoden oder verwenden Sie QObject Attribute, bis Sie dies getan haben.


bearbeiten: In Ihrem Fall Sie deepcopy ein QWidget versuchen, aber das ist nicht möglich. Python in der Lage sein, die Wrapper des QWidget zu kopieren, aber die QWidget selbst ist ein C++, die Python-Objekt kann nicht mit der Standardimplementierung von copy.deepcopy handhaben, damit, wenn Sie eine Methode der kopierten Instanz aufrufen erhalten Sie die RuntimeError, weil die Das zugrundeliegende C++ Objekt wurde nicht richtig initialisiert.

Das gleiche gilt für das Beizen dieser Objekte. Python ist in der Lage, den -Wrapper, nicht das C++ - Objekt selbst zu picken, daher ist das Ergebnis beim Entfernen der Instanz eine beschädigte Instanz.

Um deepcopy() die QWidget Klasse zu unterstützen, sollte die __deepcopy__ Methode implementieren, aber es funktioniert nicht das tun.

Wenn Sie Widgets kopieren möchten, müssen Sie alle Mechanismen manuell implementieren.

+0

Bitte lesen Sie die Antwort, die ich oben an Martijn Pieters geschrieben habe. Ich weiß jedoch nicht, wie ich meinen Code klarer teilen soll ... – Tomer

Verwandte Themen