PyQt:RuntimeError:包装的C/C++对象已被删除



如果我运行以下代码:

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

我得到这个输出:

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

我不明白为什么要删除这个对象。Window应该维护对它的引用。我已经彻底调查了这些帖子:理解"底层C/C++对象已被删除"错误是否可以查询PyQt4 QObject以确定底层C++实例是否已被破坏?

为什么要删除按钮?

这个问题的答案如下:Python PySide(内部c++对象已删除)

显然,使用setCentralWidget将一个小部件分配给QMainWindow,然后使用setCentral widget分配另一个小组件将导致底层的c++QWidget被删除,即使我有一个对象维护对它的引用。

注意:QMainWindow拥有小部件指针的所有权,并在适当的时候将其删除。

当您运行连续线程并关闭主窗口/对话框而不首先关闭线程,但在后台线程正在处理时,PyQT5中也会出现此问题。当您再次打开窗口时,第二个线程会生成并删除预先存在的小部件。在重新运行之前,您需要先退出线程。您可以通过在主窗口/对话框中检查任何小部件的可见性来退出线程

            **if self.widget.isVisible() == False:
                break**

Brain的回答完美地解释了这个问题。这个链接更详细地解释了事情。

我对这个问题的解决方案是将小部件设置为对象的属性(例如,在类方法中简单地使用self.label = ...而不是label = ...)。您可能希望对附加到小部件的任何布局执行相同的操作。

通过这种方式,您可以创建小部件的副本,这样当C++内存清理发生时,您仍然可以引用该小部件。

希望这能有所帮助。

在另一种情况下,解决方案是先将所有子对象添加到分离的布局中,然后将布局添加到父布局中作为最后一步。即:

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

wxPython&PyPubSub:

对于那些在wxPython和PyPubSub中出现相同错误的人,请在以下位置查找解决方案:

定义wx。wxpython 中的面板析构函数

以及非零()方法。

相关内容

  • 没有找到相关文章

最新更新