When you design your interface in Qt Designer and load it with uic.loadUi(), you get a fully constructed window with all the widgets you placed in Designer. But what if you want to add extra widgets after loading the .ui file — maybe a label, a button, or a dynamically created plot widget?
This is a common question, and the answer comes down to understanding layouts. In Qt, you can't just add a widget to another widget directly. You need to add it to a layout, and that layout needs to be attached to a widget. Once you understand this, adding widgets programmatically to a Designer-built interface becomes straightforward.
The Problem
Let's say you've loaded your .ui file like this:
from PyQt6 import QtWidgets, uic
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
uic.loadUi('mainwindow.ui', self)
Now you want to add a QLabel to the window. You might try something like:
self.label = QtWidgets.QLabel("Hello!")
self.addWidget(self.label) # QMainWindow has no addWidget
self.layout().addWidget(self.label) # Might return None or the wrong layout
None of these work reliably, and the errors can be confusing.
In Qt, addWidget() is a method on layouts, not on widgets. A QMainWindow, QWidget, or QPlotWidget doesn't have an addWidget() method. You need to get a reference to a layout and call addWidget() on that.
If your widget doesn't have a layout assigned, calling .layout() on it will return None, and you'll get an AttributeError when you try to call .addWidget() on it.
Use Layouts in Qt Designer
The correct approach is to set up a layout in Qt Designer, then access it from Python to add your widgets. If you're new to Qt Designer, see our first steps with Qt Designer tutorial for an introduction.
Set Up the Layout in Designer
In Qt Designer:
- Add a container widget (like a
QWidgetorQFrame) where you want your dynamic widgets to appear. - Right-click the container and choose Lay out → pick a layout type (e.g., Lay out Vertically).
- Give the container a meaningful
objectNamein the Property Editor — for example,dynamicWidgetContainer.
When you use uic.loadUi('mainwindow.ui', self), all named objects from the .ui file become attributes on self. So if your container widget is named dynamicWidgetContainer, you can access it as self.dynamicWidgetContainer in your Python code.
Add Widgets in Python
Once your container has a layout, you can access it and add widgets:
from PyQt6 import QtWidgets, uic
import sys
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
uic.loadUi('mainwindow.ui', self)
# Create a new label
self.label = QtWidgets.QLabel("I was added from Python!")
# Add it to the container's layout
self.dynamicWidgetContainer.layout().addWidget(self.label)
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
This works because self.dynamicWidgetContainer is a QWidget that has a layout assigned in Designer. Calling .layout() on it returns that layout, and you can then call .addWidget() to insert your new widget.
What If You Don't Have a Layout Yet?
If the container widget doesn't have a layout set in Designer, .layout() will return None. In that case, you can create a layout in Python and assign it:
from PyQt6 import QtWidgets, uic
import sys
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
uic.loadUi('mainwindow.ui', self)
# Create a layout and set it on the container
layout = QtWidgets.QVBoxLayout()
self.dynamicWidgetContainer.setLayout(layout)
# Now add widgets to it
self.label = QtWidgets.QLabel("Added dynamically!")
layout.addWidget(self.label)
self.button = QtWidgets.QPushButton("Click me")
layout.addWidget(self.button)
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
One thing to watch out for: if a layout is already set on the widget (from Designer), calling setLayout() again won't replace it — Qt will print a warning and ignore the new layout. So check whether a layout already exists first, or just set one up in Designer to avoid the issue entirely. For a deeper look at how layouts work in PyQt6, see our layouts tutorial.
Working with QMainWindow's Central Widget
QMainWindow is a special case. It uses a central widget rather than a simple layout. When you design a QMainWindow in Designer, the central widget and its layout are already configured in the .ui file.
If you want to add widgets to the main area of a QMainWindow, you should add them to the central widget's layout, not to the QMainWindow directly. You can access it like this:
self.centralWidget().layout().addWidget(self.label)
Or better yet, place a named container widget inside the central widget in Designer and target that specifically. This gives you more control over exactly where your dynamic widgets appear.
Checking Widget Names from Your .ui File
If you're not sure what names your widgets have, you have a few options:
Check in Qt Designer. Click on any widget in Designer and look at the objectName property in the Property Editor panel (usually on the right side). This is the name you'll use in Python.
Convert the .ui file to Python. You can use the pyuic6 command-line tool to convert your .ui file into a Python file, then inspect the generated code:
pyuic6 mainwindow.ui -o mainwindow_ui.py
Open mainwindow_ui.py and you'll see exactly how every widget is created and named. This is really helpful for understanding the structure of your interface. For a complete guide to designing interfaces with Qt Designer, including how to use layouts and the property editor, check out our Qt Designer GUI layout tutorial.
Summary
To add widgets after loading a .ui file:
- Make sure the target container widget in your
.uifile has a layout applied to it (set this up in Qt Designer). - Access the container by its
objectName— afterloadUi, it becomes an attribute onself. - Get the layout with
.layout()and call.addWidget()to insert your new widget.
If you're ever unsure about the structure of your .ui file, convert it to Python with pyuic6 and read through the generated code. It's a great way to see exactly how your interface is put together. To learn more about the available widgets you can add to your interfaces, take a look at our PyQt6 widgets tutorial.
Packaging Python Applications with PyInstaller by Martin Fitzpatrick
This step-by-step guide walks you through packaging your own Python applications from simple examples to complete installers and signed executables.