Jump to content

  • Log In with Google      Sign In   
  • Create Account

PyQt4 - takeAt() returning a QWidgetItem?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 TheComet   Members   -  Reputation: 1568

Like
0Likes
Like

Posted 20 August 2014 - 08:32 AM

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, 20 August 2014 - 08:33 AM.

YOUR_OPINION >/dev/null


Sponsor:

#2 Aardvajk   Crossbones+   -  Reputation: 5980

Like
0Likes
Like

Posted 20 August 2014 - 08:42 AM

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.



#3 TheComet   Members   -  Reputation: 1568

Like
0Likes
Like

Posted 20 August 2014 - 09:28 AM

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, 20 August 2014 - 09:28 AM.

YOUR_OPINION >/dev/null


#4 Aardvajk   Crossbones+   -  Reputation: 5980

Like
0Likes
Like

Posted 20 August 2014 - 12:11 PM

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.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS