[PySide] Problem with garbage collection

henry.wede at yahoo.com henry.wede at yahoo.com
Thu Feb 9 23:15:48 CET 2023


 David,
Thanks for looking that up.  It knew learning C++ would make me a better Python programmer :)  Seems too hard though...
My method probably does seem strange, but I will try to explain it.  I have to store a bunch of lists containing both commands and robot positions.  I made different objects to store the items information because it keeps things organized.  It is easy to access Position.CoordinateSystem and things like that.  The program has many list of these objects.  
Then I thought that I would be clever... since I am making objects anyway, why not derive those objects from a QListWidgetItem?  Then when I need to display the objects I can just add them to a list widget and the displaying is done in only a couple lines of code.  Also, the program can change the icons or text color with just a couple lines.  But I only use one list widget to display the all of the lists - one at a time, of course.  The list widget is reused/recycled.
That is why I am putting things into a list widget, moving them around, storing them, clearing the list widget and doing it again.Probably not what the folks at Qt thought I was going to do.
Henry

    On Thursday, February 9, 2023 at 02:55:39 PM MST, David Ching <dc at dcsoft.com> wrote:  
 
 >from: "henry.wede at yahoo.com" <henry.wede at yahoo.com>

Henry> it seems like the clear method of the listwidget was the problem.?
Here is what I tried.
[...]
 The objects are ~just~ created from XML.  When I display those items using
the ListWidget .addItem() method they display correctly.? But only the first
time!? If I clear the list and display the same objects in the same list a
second time then I get the error. So it seems that the addItem method "takes
control" of the object in the Python list and the clear() method destroys
the internal object - even though I can print the objects in the Python list
so they seem to still exist. They are like zombies without a C++ soul :) 
[...]
Lastly, I eliminated the trouble-causing clear() method completely and now
"remove" the list items manually like this:
for N in range( ListWidget.count(), -1, -1): 
    Whatever = ListWidget.takeItem(N) 
I don't feel very professional doing it this way, but it seems to be
working.

The C++ code for QListWidget::clear() is as follows.  

 1: // NOTE:  QListWidget::clear() calls QListModel::clear()
 2: void QListModel::clear()
 3: {
 4:    beginResetModel();
 5:    for (int i = 0; i < items.count(); ++i) {
 6:        if (items.at(i)) {
 7:            items.at(i)->d->theid = -1;
 8:            items.at(i)->view = nullptr;
 9:            delete items.at(i); 
10:        }
11:    }
12:    items.clear();
13:    endResetModel();
14: }


So yes, on line 9, the QListWidgetItem C++ object is deleted (so it's
"soul") is indeed destroyed!  This is printed in red at
https://doc.qt.io/qt-6/qlistwidget.html#items:  "Warning: All items will be
permanently deleted."

Why do you need to access the QListWidgetItem after you clear it from the
list?  Perhaps you should create new QListWidgetItem's and call
QListWidget.addItem() for those new instances instead.  

Or just use QListWidget.takeItem() as you have done.  Nothing wrong with
that.  

I have also found QListWidgetItem.setHidden() to be great as it lets me keep
the item in the list but the user has no knowledge.

Good luck,
David 




  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/pyside/attachments/20230209/db33c788/attachment.htm>


More information about the PySide mailing list