[Tutor] underlying C/C++ object has been deleted

David Boddie david at boddie.org.uk
Sun Oct 28 00:39:58 CEST 2007


On Thu Oct 25 06:45:38 CEST 2007, Lawrence Shafer wrote:

> I am trying to convert a program with hand coded QT over to using UI 
> files from QT Designer. I am getting the error below and do not 
> understand what's going on.

This error occurs when an object referred to by Python and Qt is deleted
by Qt (i.e, on the C++ side), leaving a dangling reference on the Python
side. There is another common error people make with this that occurs
when a QObject subclass isn't initialized properly, but I don't think
that this is the case here.

> I have a feeling I need to add self. to  
> something in here, but I'm not sure what.

Adding self may not help, but it depends on the exact problem.

> Is this enough code for you to  
> see whats going on?? If not I can upload the project somewhere.  Thanks, 
> Lawrence
> 
> The error,
> 
> Traceback (most recent call last):
>   File "atf.py", line 113, in on_actionOpen_triggered
>     self.open()
>   File "atf.py", line 56, in open
>     if self.isUntitled and self.textBrowser.document().isEmpty() and not 
> self.isWindowModified():
> RuntimeError: underlying C/C++ object has been deleted

It's difficult to know what went wrong without being able to experiment
with the code to determine exactly which object has been deleted, and the
file you referred to in your later message doesn't contain the code that
this traceback refers to, so it's a little difficult to diagnose the
problem.

However, as you suggest, it seems that you're doing some strange things with
the .ui file.

In your class's __init__() method, you first call the init() method, in
which you create a QTextBrowser widget and set it as the central widget of
your QMainWindow subclass:

    def init(self):
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        self.isUntitled = True
        self.textBrowser = QtGui.QTextBrowser()
        self.setCentralWidget(self.textBrowser)
        self.connect(self.textBrowser.document(),
            QtCore.SIGNAL("contentsChanged()"), self.documentWasModified)

What implicitly happens here is that the QMainWindow takes ownership of
the QTextBrowser on the C++ side.

Then, after doing that, you instantiate the Ui_mainWindow class which was
created using Qt Designer and set up its user interface within your
QMainWindow subclass:

        self.ui = Ui_mainWindow()
        self.ui.setupUi(self)

Since the user interface defined in this class will almost certainly contain
a central widget of its own, your original central widget will be replaced
and, since it is being maintained on the C++ side, it will be deleted.
This means that you are left with a reference to a deleted object
(self.textBrowser) and the signal-slot connection you made in init() will
have been broken.

The solution to this is to set up the QTextBrowser using Qt Designer. Just
drag it into the central area of the main window and apply a layout.

Hope this helps,

David



More information about the Tutor mailing list