• Advertisement
Sign in to follow this  

PyQt4 - takeAt() returning a QWidgetItem?

This topic is 1252 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,
 
I've discovered some very strange behaviour when trying to delete a QWidget from a QGridLayout. The following code demonstrates this behaviour:
 
>>> from PyQt4 import QtGui
>>> import sys
>>> app = QtGui.QApplication(sys.argv)
>>> grid_layout = QtGui.QGridLayout()
>>> grid_layout.addWidget(QtGui.QWidget())
>>> item = grid_layout.takeAt(0)
>>> item.deleteLater()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'QWidgetItem' object has no attribute 'deleteLater'
 
I swear this has worked before.
 
This makes no sense to me whatsoever. Firstly, why is it returning a QWidgetItem when I inserted a QWidget to begin with? Secondly, every Qt object derives from QObject, and deleteLater() is a method of QObject, so that method should exist. What's going on here?
 
Additional info:
Python 2.7.6 (default, Mar 22 2014, 22:59:56)
[GCC 4.8.2] on linux2
Edited by TheComet

Share this post


Link to post
Share on other sites
Advertisement

Can't speak for Python, but in the C++ Qt, takeAt has always returned a QWidgetItem. When you add a widget to a layout, it creates a QWidgetItem under the scenes, which is what is always (and has always) been returned by things like itemAt(), takeAt() etc.

 

Layouts store QLayoutItems, not widgets, so a widget has to be contained in a descendant of QLayoutItem.

 

You can access the QWidgetItem::widget() if you need to. If memory serves, there is some odd behaviour with ownership here and you need to delete the widget, then the widget item to properly remove it, although again this is C++ and I'm not 100% sure I'm remembering that right.

Share this post


Link to post
Share on other sites

It's strange because I could have sworn I've used the following code before in other projects:

while layout.count():
    layout.takeAt(0).deleteLater()

Anyway, the following seems to work just fine:

layout.takeAt(0).widget().deleteLater()
Edited by TheComet

Share this post


Link to post
Share on other sites

It's strange because I could have sworn I've used the following code before in other projects:

while layout.count():
    layout.takeAt(0).deleteLater()
Anyway, the following seems to work just fine:
layout.takeAt(0).widget().deleteLater()

I'm not sure the QLayoutItem is being deleted there. No idea if it matters in Python but in C++ takeAt transfers ownership of the QLayoutItem to the caller and the layout no longer owns it.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement