12

I would like to create a widget that has a child widget that I can dynamically change. Here is what I tried:

import sys
from PySide.QtCore import *
from PySide.QtGui import *

class Widget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setLayout(QVBoxLayout())
        self.child = QLabel("foo", self)
        self.layout().addWidget(self.child)
    def update(self):
        self.layout().removeWidget(self.child)
        self.child = QLabel("bar", self)
        self.layout().addWidget(self.child)

app = QApplication(sys.argv)
widget = Widget()
widget.show()
widget.update()
app.exec_()

The problem is that this doesn't actually remove the "foo" label visually. It is still rendered on top of "bar". Screenshot of the problem. How do I remove the old widget so that only the new widget is shown?

I know that I can change the text property of the label. This is not what I want in my application, I need to change the actual widget (to a different widget type).

Jules
  • 6,318
  • 2
  • 29
  • 40

1 Answers1

22

removeWidget() only removes the item from the layout, it doesn't delete it. You can delete the child widget by calling setParent(None).

def update(self):
    self.layout().removeWidget(self.child)
    self.child.setParent(None)
    self.child = QLabel("bar", self)
    self.layout().addWidget(self.child)
Stephen Terry
  • 6,169
  • 1
  • 28
  • 31
  • 1
    Thanks a lot! That works :) Do I need to remove the widget from the layout? Not removing it seems to work, but maybe this has problems? – Jules Jun 20 '11 at 12:21
  • 6
    Poking around a bit in the debugger, it looks like the garbage collection is smart enough to remove the reference in the Layout. So I don't think it would cause a problem. – Stephen Terry Jun 20 '11 at 13:30