PyQt4 嵌套类 - "RuntimeError: 底层 C/C++ 对象已被删除

1 投票
2 回答
1471 浏览
提问于 2025-04-17 16:55

我正在尝试制作一个很酷的应用程序,但感觉自己缺乏一些知识。我在网上读了很多信息和例子,但似乎没有帮助:理解“底层 C/C++ 对象已被删除”错误


好吧,我来讲讲我做了什么:

我从我的 main.py 创建了一个中央小部件,这部分运行得很好,我就不在这里完整贴出来了:

self.rw = ReportWidget()
self.setCentralWidget(self.rw)

这是我的中央小部件 - report.py

#! /usr/bin/env python
# -*- coding: utf-8 -*-

from PyQt4 import QtGui, QtCore

class ReportWidget(QtGui.QWidget):
    def __init__(self, parent=None):
        super(ReportWidget, self).__init__(parent)
        self.setup_ui()

    def setup_ui(self):
        report = QtGui.QVBoxLayout(self)
        report.setAlignment(QtCore.Qt.AlignTop)

        head = QtGui.QHBoxLayout()
        add_label = QtGui.QLabel(u"Add")
        head.addWidget(add_label)

        report.addLayout(head)

        area = QtGui.QScrollArea()
        area.setWidgetResizable(True)
        area.setEnabled(True)
        layout = QtGui.QVBoxLayout()
        layout.setAlignment(QtCore.Qt.AlignTop)
        widget = QtGui.QWidget()
        widget.setLayout(layout)
        area.setWidget(widget)
        report.addWidget(area)

        self.s = layout

        # trying to create first line:
        first_line = Line(self)
        self.s.addWidget(first_line)        
        first_line.set_controls(True, False)

        head = QtGui.QHBoxLayout()
        ok = QtGui.QPushButton(u"Calculate")

        head.addWidget(ok)
        report.addLayout(head)

接下来是同一个文件 report.py 的内容:

class Line(QtGui.QWidget):
    def __init__(self, parent=None):
        super(Line, self).__init__(parent)
        self.setup_ui(parent)

    def setup_ui(self, parent):
        add_button = QtGui.QPushButton()
        add_button.setObjectName("add_button")

        self.add_button = add_button
        self.layout = QtGui.QHBoxLayout(line)
        self.layout.addWidget(add_button)

    def set_controls(self, add_button=True, remove_button=True):
        self.add_button.setEnabled(add_button)

所以,运行 main.py 时,在我尝试给新按钮设置 setEnabled 参数的最后一段代码时,出现了 RuntimeError: underlying C/C++ object has been deleted 的错误,就好像这个按钮从来没有被创建或绑定到任何地方似的。

看起来我可能有一些设计上的问题。也许把不同的类放在一个文件里是个错误?或者我可能不太清楚哪个小部件有哪个父级,以及布局是怎么工作的。


谢谢你的阅读。祝你有美好的一天!

2 个回答

0

我没有能重现你给我们展示的代码中的错误(除了一个关于变量 lineLine.setup_ui 中未定义的错误)。如果我把 line 替换成 self,就没有错误了。

不过,如果我把 line 设置为一个我创建的 QWidget,但没有保存对它的引用,那就会崩溃。换句话说,我在

    line = QtGui.QWidget()

中添加了这段代码,然后发现它在你报告的同一行代码上崩溃了,提示说被包装的 C/C++ 对象已经被删除。

1

感谢大家尝试回答我的问题!可惜没有人说我写的东西有多糟糕!*微笑*

我的 line 已经是一个小部件了,我不需要在它内部再创建一个自己。其实我只需要在 setup_ui 里面创建布局,然后把小部件添加进去。最后的代码看起来是这样的:

class Line(QtGui.QWidget):
    def __init__(self, parent=None):
        super(Line, self).__init__(parent)
        self.setup_ui(parent)

    def setup_ui(self, parent):
        line = QtGui.QHBoxLayout(self)

        add_button = QtGui.QPushButton()
        add_button.setObjectName("add_button")

        line.addWidget(add_button)

        # to get reference from outside
        self.add_button = add_button

    def set_controls(self, add_button=True, remove_button=True):
        self.add_button.setEnabled(add_button)

特别感谢 nymkAvaris

撰写回答