I tried to do some operation (setParent
) on an object in Python (an instance of a class which inherits from a different class - to be specific, QtGui.QLabel
), but during runtime the above error was raised. The object itself has had some fields with actual content (verified on debug), but from some reason I couldn't "use" it. What does the error mean and how can I fix it? For some additional information, I shall say that the object was returned from a static method before I tried to do this operation on it.
The subclass has a __init__()
function of its own:
def __init__(self, image, father):
super(AtomicFactory.Image, self).__init__(father)
self.raw_attributes = image.attributes
self.attributes = {}
father.addChild(self)
self.update()
Now I wrote a similar code, a simple one, that had the same error on the line widget.setParent(mw)
when the window was moved.
#!/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_())
What was the problem?
If you want to inherit QObject
(or QWidget
), you must always call the super-class __init__
:
class MyObject(QObject):
def __init__(self, *args, **kwargs):
super(MyObject, self).__init__(arguments to parent class)
#other stuff here
You may also call the parent's class's __init__
after some instructions, but you can't call QObject
methods or use QObject
attributes until you did so.
Edit:
In your case you are trying to deepcopy
a QWidget
, but this is not possible.
Python may be able to copy the wrapper of the QWidget
, but the QWidget
itself is a C++ object that python cannot handle with the default implementation of copy.deepcopy
, hence whenever you call a method of the copied instance you get the RuntimeError
because the underlying C++ object wasn't initialized properly.
The same is true for pickling these objects. Python is able to pickle the wrapper, not the C++ object itself, hence when unpickling the instance the result is a corrupted instance.
In order to support deepcopy()
the QWidget
class should implement the __deepcopy__
method, but it does not do that.
If you want to copy widgets you'll have to implement by yourself all the mechanism by hand.
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