How to replace a Widget with another using Qt?

The most common solution is to use QStackedWidget and put all possible widgets into the stack. When selecting an item, just call setCurrentWidget to display the one you want.


I have the same question as Natim.

The QStackedWidget is a solution for a preset layout. It acts like the flippy thing in an old diner for a music box. (X-amount of albums in the jukebox, flip through the installed albums).

However this does not solve the question.

For instance I have code I am prototyping with a UI layout, however I want to replace some of the widgets that are acting as place-holders with the proper widgets that are coded during the primary script execution, or is dynamically created.

I am sure there is a simple procedure or caveat as to how to properly remove/replace a widget.

The code I have has a basic textEdit widget in a grid layout. I want to code a custom version of this widget for drag and drops and then swap it out with the default textEdit.

Like Natim, the code seems logically sound, however the widgets are hap-hazardly piled in the layout like dumping a purse.

Hopefully can figure out the trick to this and repost the caveat.

SOLUTION:

Voilà!! Found something that definitely does the trick. CLOSE your widget

#  Remove, Create, Replace
    self.ui.gridLayout.removeWidget(self.ui.dragDataEdit)
    self.ui.dragDataEdit.close()
    self.ui.dragDataEdit = myDumpBox(self.ui.centralwidget)
    self.ui.gridLayout.addWidget(self.ui.dragDataEdit, 0, 0, 1, 1)
    self.ui.gridLayout.update()

I removed the widget from the layout, then closed the widget. At this time the variable I am using is open to create my custom/modified widget, and then re-insert it into the layout

Yes some more elegance is needed to deal with more complicated layouts, but the basic need of destroying a widget in order to replace it is in the .close() method

Cheers.. hope this helps. B


Actually, as for Qt5 at least, there is a more compact alternative to B4adle7's solution utilizing QLayout's replaceWidget:

containing_layout = placeholder.parent().layout()
containing_layout.replaceWidget(placeholder, new_widget)

Extra hint:

You want to put a custom widget into place with this at runtime and you are using ui-files? Use promoting to custom widgets instead! Here is a good post with screenshots about how to configure a custom widget inside Qt designer for PyQt.

In PySide this works similar. Instead of specifying the source file of the custom widget as header file, you would register your custom widget class in the QUiLoader instance used to load the ui-file via registerCustomWidget() in Python code.

Tags:

Python

Qt

Pyqt