views:

158

answers:

2

I've got a QFrame with a QVBoxLayout and I'm adding my own custom widgets to the layout to simulate a QListWidget but with more information/functionality in the items. I add the widget to the layout and keep a reference in a member variable (this is Python):

 self.sv_widgets[purchase.id] = widget                
 self.vl_seatView.addWidget(widget)

Then when I'm done with an item I want to remove it from the screen and clean up the reference:

self.vl_seatView.removeWidget(self.sv_widgets[purchase.id])
del self.sv_widgets[purchase.id]

Unfortunately, the widget is still being displayed on the screen! I've checked and I'm only adding it to the layout once (and indeed only one copy is displayed), tried manually calling update() on the layout, but to no avail. What's the right way to do this?

+3  A: 

You can do this:

import sip # you'll need this import (no worries, it ships with your pyqt install)
sip.delete(self.sv_widgets[purchase.id])

sip.delete(obj) explicitely calls the destructor on the corresponding C++ object. removeWidget does not cause this destructor to be called (it still has a parent at that point) and del only marks the Python object for garbage collection.

You can achieve the same by doing (propably cleaner):

self.vl_seatView.removeWidget(self.sv_widgets[purchase.id])
self.sv_widgets[purchase.id].setParent(None)
del self.sv_widgets[purchase.id]
ChristopheD
That does indeed work if I use that instead of just letting it be garbage collected. Why doesn't just removing it from the layout remove it from the screen?
gct
I've updated the answer with an explanation and another way of achieving the same.
ChristopheD
Excellent, I never would have figured this out on my own, thanks.
gct
A: 

You can also use self.sv_widgets[purchase.id].deleteLater()

agateau