PyQt4 nested classes - “RuntimeError: underlying C

2019-08-08 07:36发布

问题:

I'm trying to build a cool app, but it seems I lack some knowledge. Read lots of infos and examples in internet, but it doesn't help: Understanding the "underlying C/C++ object has been deleted" error


Ok, here what I do:

I create central widget from my main.py, which works fine and I don't post it here fully:

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

And here is my central widget - 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)

Continued from the same file 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)

Thus, running main.py raises RuntimeError: underlying C/C++ object has been deleted error on the last piece of code where I try to setEnabled parameter to new button, as if it was never created or bound anywhere.

It seems I have some design flaw. Maybe it's wrong idea to have different classes in one file or else? Or maybe I don't quite control which widget has which parent and how layouts work.


Thank you for reading. Have a nice day!

回答1:

Thanks to everyone who tried to answer! Unfortunately no one said what a bunch of crap I wrote! *smile*

My line is already a widget and I don't need to create itself inside itself. All I had to do is to create layout inside setup_ui and add widgets to it. Finally it looks like:

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)

Special thanks to nymk and Avaris!



回答2:

I could not reproduce an error with the code you showed us (apart from an error about the variable line not being defined in Line.setup_ui). If I replaced line with self, I got no error.

However, I could get a crash if I set line to a QWidget that I created and didn't keep a reference to. In other words, I added

    line = QtGui.QWidget()

to Line.setup_ui, and found that this crashed on the same line of code you reported, complaining that the wrapped C/C++ object had been deleted.



标签: python pyqt4