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).

1 Answer 1

23

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)
Sign up to request clarification or add additional context in comments.

2 Comments

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?
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.