2012-09-05 12 views
9

Intenté hacer alguna operación (setParent) en un objeto en Python (una instancia de una clase que hereda de una clase diferente, para ser específico, QtGui.QLabel), pero durante el tiempo de ejecución se produjo el error anterior. El objeto en sí tiene algunos campos con contenido real (verificado en depuración), pero por alguna razón no pude "usarlo". ¿Qué significa el error y cómo puedo solucionarlo? Para obtener información adicional, diré que el objeto fue devuelto por un método estático antes de intentar hacer esta operación en él.Python: RuntimeError: super-clase __init __() de% S nunca se llamó

La subclase tiene una función __init__() de su propia:

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

Ahora me escribió un código similar, muy simple, que tenía el mismo error en la línea widget.setParent(mw) cuando la ventana se movió.

#!/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_()) 

¿Cuál fue el problema?

+0

Si su clase derivada 'MyDerived' tiene su propio' __init__' intente agregar la línea 'super (MyDerived, self) .__ init __()'. – halex

+0

Lo hace. El objeto realmente se creó antes y se usó bien. También podría haber usado setParent() sin problemas en la etapa inicial. Luego se insertó en una lista y el método estático que describí anteriormente "lo encontró" dentro de la lista y luego lo devolvió a otro método estático. Cuando este último intentó usar setParnet() en él, se devolvió el error. De todos modos, la función personalizada __init __() de la subclase es: – Tomer

+0

def __init __ (self, image, father): super (AtomicFactory.Image, self) .__ init __ (father) self.raw_attributes = image.attributes self.attributes = {} father.addChild (self) self.update() – Tomer

Respuesta

15

Si desea heredar QObject (o QWidget), siempre hay que llamar a la super-clase __init__:

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

También puede llamar de __init__ clase de los padres después de algunas instrucciones, pero no se puede llamar QObject métodos o use los atributos QObject hasta que lo haga.


Editar: En el caso de que están tratando de deepcopy un QWidget, pero esto es no posible. Python puede ser capaz de copiar el envoltorio del QWidget, pero el QWidget sí es un objeto de C++ que Python no puede manejar con la implementación predeterminada de copy.deepcopy, por lo tanto, cada vez que se llama a un método de la instancia de copiado se obtiene el RuntimeError porque el el objeto C++ subyacente no se inicializó correctamente.

Lo mismo es cierto para decapado de estos objetos. Python puede encuadrar el contenedor , no el objeto C++ en sí mismo, por lo tanto, al desatornillar la instancia, el resultado es una instancia dañada.

Con el fin de apoyar a la clase deepcopy()QWidget debe implementar el método __deepcopy__, pero eso no hacer eso.

Si desea copiar widgets tendrá que implementar usted mismo todo el mecanismo a mano.

+0

Consulte la respuesta que le escribí a Martijn Pieters. Sin embargo, no sé cómo compartir mi código de una manera más clara ... – Tomer

Cuestiones relacionadas