PyQt: RuntimeError: completed C / C ++ object removed

If I run this code:

#!/usr/local/bin/ python3 import sys from PyQt4.QtCore import * from PyQt4.QtGui import * class Window(QMainWindow): def __init__(self): super().__init__() self.button1 = QPushButton("1") self.button2 = QPushButton("2") self.setCentralWidget(self.button1) self.button1.clicked.connect(lambda: self.setCentralWidget(self.button2)) self.button2.clicked.connect(lambda: self.setCentralWidget(self.button1)) self.show() if __name__ == '__main__': import sys app = QApplication(sys.argv) window = Window() sys.exit(app.exec_()) 

... I get this output:

 Traceback (most recent call last): File "test.py", line 16, in <lambda> self.button2.clicked.connect(lambda: self.setCentralWidget(self.button1)) RuntimeError: wrapped C/C++ object of type QPushButton has been deleted 

I do not understand why the object is being deleted. The window should contain a link to it. I carefully studied these posts: It is clear that the error "the underlying C / C ++ object has been removed" Can I query QQbject PyQt4 to determine if the original C ++ instance was damaged?

Why is the button deleted?

+10
garbage-collection pyqt pyqt4 qobject qmainwindow
source share
3 answers

This answer to this question is found here: Python PySide (internal C ++ object already deleted)

Apparently, assigning one QMainWindow widget using setCentralWidget and then assigning another widget using setCentralWidget will remove the hidden CWidget C ++, although I have an object that maintains a reference to it.

Note. QMainWindow takes control of the widget pointer and deletes it at the appropriate time.

+11
source share

The answer to the brain perfectly explains the problem. This link explains the details in more detail.

My solution to this problem was to set widgets as attributes of an object (for example, just using self.label = ... instead of label = ... in your class methods). You might want to do the same for any layouts attached to the widget.

This way you create a copy of the widget so that when you clear the C ++ memory, you still have a link to the widget.

Hope this helps.

0
source share

In another case, the solution was to first add all the child objects to a separate layout, and as a last step, add the layout to the parent layout. I.e:

  l = QGridLayout() l.addWidget(QLabel("child1"), 0, 0) l.addWidget(QLabel("child2"), 0, 1) ... parentLayout.addLayout(l) 
0
source share

All Articles