Correct way to address Pyside Qt widgets from a .ui file via Python
Categories:
Accessing PySide/PyQt Widgets from .ui Files in Python

Learn the correct and robust methods to interact with Qt widgets defined in .ui files using Python with PySide6 or PyQt6.
When developing graphical user interfaces (GUIs) with PySide or PyQt, it's common practice to design the UI visually using Qt Designer and save it as a .ui
file. This separates the UI layout from the application logic. However, a frequent challenge for developers is understanding how to correctly access and manipulate these UI elements (widgets) from their Python code. This article will guide you through the most effective and recommended ways to bridge this gap, ensuring your Python application can seamlessly interact with your .ui
defined widgets.
Understanding the .ui File and Widget Naming
A .ui
file is an XML-based description of your GUI. It defines the layout, properties, and hierarchy of all widgets. Crucially, each widget in Qt Designer has an objectName
property. This objectName
is the key identifier that your Python code will use to reference the widget. It's vital to give meaningful and unique objectName
s to all widgets you intend to interact with programmatically.
flowchart TD A[Qt Designer] --> B[".ui" File (XML)]; B --> C{Widget Definition}; C --> D["objectName" Property]; D --> E[Python Code]; E --> F["findChild()" or "Attribute Access"]; F --> G[Interact with Widget];
Workflow for accessing .ui defined widgets in Python.
Method 1: Using uic.loadUi()
and Direct Attribute Access
The simplest and often most convenient way to load a .ui
file and access its widgets is by using uic.loadUi()
(for PyQt) or QUiLoader().load()
(for PySide). This method dynamically creates a Python object representing your UI, and all widgets with an objectName
become direct attributes of this object. This approach is generally recommended for its simplicity and readability.
import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel
from PySide6.QtUiTools import QUiLoader
# Assuming 'my_window.ui' contains a QMainWindow with a QPushButton named 'myButton' and a QLabel named 'myLabel'
class MyWindow(QMainWindow):
def __init__(self):
super().__init__()
# Load the UI file directly into this QMainWindow instance
loader = QUiLoader()
loader.load('my_window.ui', self)
# Access widgets directly by their objectName
self.myButton.clicked.connect(self.on_button_click)
self.myLabel.setText("Initial text from Python")
def on_button_click(self):
self.myLabel.setText("Button clicked!")
print("Button was clicked!")
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec())
Example of loading a .ui file and accessing widgets via direct attribute access using PySide6.
.ui
file is in the same directory as your Python script, or provide the full path to the .ui
file. For PyQt, replace from PySide6.QtUiTools import QUiLoader
with from PyQt6 import uic
and loader.load('my_window.ui', self)
with uic.loadUi('my_window.ui', self)
.Method 2: Using findChild()
for Dynamic Access
While direct attribute access is convenient, there might be scenarios where you need to access widgets dynamically, perhaps based on a generated name or when iterating through a collection of similar widgets. The findChild()
method (available on any QWidget
) allows you to search for a child widget by its type and objectName
. This method is more robust if you're unsure of the exact widget type or need to perform a more generic search.
import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel
from PySide6.QtUiTools import QUiLoader
class MyWindowWithFindChild(QMainWindow):
def __init__(self):
super().__init__()
loader = QUiLoader()
loader.load('my_window.ui', self)
# Access widgets using findChild()
self.button = self.findChild(QPushButton, 'myButton')
self.label = self.findChild(QLabel, 'myLabel')
if self.button:
self.button.clicked.connect(self.on_button_click)
if self.label:
self.label.setText("Initial text via findChild")
def on_button_click(self):
if self.label:
self.label.setText("Button clicked via findChild!")
print("Button was clicked (findChild)!")
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyWindowWithFindChild()
window.show()
sys.exit(app.exec())
Example of accessing widgets using the findChild() method in PySide6.
findChild()
returns a valid widget (i.e., not None
) before attempting to interact with it. This prevents AttributeError
if a widget with the specified name and type is not found.Method 3: Compiling .ui to .py (Less Common but Useful)
Another approach, though less common for direct widget access, is to compile your .ui
file into a Python module (.py
file). This is done using the pyside6-uic
(or pyuic6
for PyQt6) command-line tool. This generated Python file contains a class that sets up the UI. You then inherit from this generated class in your application code. This method can be useful for deployment or when you prefer not to load the .ui
file at runtime.
pyside6-uic my_window.ui -o ui_my_window.py
Command to compile a .ui file into a Python module using PySide6.
import sys
from PySide6.QtWidgets import QApplication, QMainWindow
from ui_my_window import Ui_MainWindow # Import the generated UI class
class MyCompiledWindow(QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self) # Set up the UI defined in ui_my_window.py
# Widgets are now attributes of self, just like with loadUi()
self.myButton.clicked.connect(self.on_button_click)
self.myLabel.setText("Initial text from compiled UI")
def on_button_click(self):
self.myLabel.setText("Button clicked (compiled)!")
print("Button was clicked (compiled)!")
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyCompiledWindow()
window.show()
sys.exit(app.exec())
Example of using a compiled .ui file in a PySide6 application.
.py
file will contain a class (e.g., Ui_MainWindow
) with a setupUi
method. You call this method on your QMainWindow
(or QWidget
) instance to initialize the UI. Widgets are then accessible as attributes, similar to the uic.loadUi()
method.