Using a Designer UI File in Your Qt for Python Application

Converting the Form to Python Code

To demonstrate, we use the Qt Widgets animation easing example.

The application consists of one source file, easing.py, a UI file form.ui, a resource file easing.qrc and the project file, easing.pyproject file in the YAML format:

 {
     "files": ["easing.qrc", "ui_form.py", "easing.py", "easing_rc.py",
               "form.ui"]
 }

The UI file is converted to Python code building the form using the User Interface Compiler (uic):

 uic -g python form.ui > ui_form.py

Since the top level widget is named Form, this results in a Python class named Ui_Form being generated. It provides a function setupUi(), taking the widget as parameter, which is called to create the UI elements:

 from ui_form import Ui_Form
 ...
 class Window(QtWidgets.QWidget):
     def __init__(self, parent=None):
         super(Window, self).__init__(parent)

         self.m_ui = Ui_Form()
         self.m_ui.setupUi(self)

Later on, the widgets can be accessed via the Ui_Form class:

 self.m_ui.graphicsView.setScene(self.m_scene)

Besides setupUi(), Ui_Form provides another method retranslateUi(), which can be called in reaction to a QEvent of type QEvent.LanguageChange, which indicates a change in the application language.

The UiTools Approach

The QUiLoader class provides a form loader object to construct the user interface at runtime. This user interface can be retrieved from any QIODevice, e.g., a QFile object. The QUiLoader::load() function constructs the form widget using the user interface description contained in the file.

It is demonstrated by the uiloader example:

 from PySide2.QtUiTools import QUiLoader

 if __name__ == '__main__':
     # Some code to obtain the form file name, ui_file_name
     app = QApplication(sys.argv)
     ui_file = QFile(ui_file_name)
     if not ui_file.open(QIODevice.ReadOnly):
         print("Cannot open {}: {}".format(ui_file_name, ui_file.errorString()))
         sys.exit(-1)
     loader = QUiLoader()
     widget = loader.load(ui_file, None)
     ui_file.close()
     if not widget:
         print(loader.errorString())
         sys.exit(-1)
     widget.show()
     sys.exit(app.exec_())

Resource imports

Single directory usage

When using icons from resource files, say resources.qrc, uic will generate an import of the form:

 import resources_rc

This assumes that a file resources_rc.py generated by calling the Resource Compiler (rcc) tool (passing the -g python command line option) exists in the same directory as the form source.

uic has a command line option --rc-prefix causing the rc indicator to be prepended:

 import rc_resources

The command line option --from-imports causes the imports to be generated relative to '.':

 from . import resources_rc

Directory trees

Some projects have more complicated directory trees, for example:

 project
     resources   (resources.qrc)
     ui          (.ui files)

The resource file is then not in the same directory as the form source and the .ui files typically have relative paths to the resource files:

 <include location="../resources/resources.qrc"/>

In this case, the command line option --absolute-imports can be used to generate an absolute import in Python, resulting in:

 import resources.resources_rc

based on the assumption that .. is the root directory of the project contained in the Python import path list.

For more deeply nested trees, it is possible to use the command line option --python-paths <path list> to pass a Python import path list. uic will then try to determine the project root by matching the form file path against the path components.

If --python-paths is not given, the environment variable PYTHONPATH is by default checked.