PyQt5 is a Python package that provides a wrapper for accessing the Qt framework libraries. Qt is a cross platform widget toolkit that allows creating graphical user interfaces. It supports Windows, Android, Linux and Mac. Several options exist for developing GUI applications using Python. For example Pyside, TKinter, PyGTK and Kivy are Python packages for creating GUI applications
The obvious benefit of GUI applications is that they allow the data to remain on the local computer. Also the GUI application is always available since it does not depend on internet connectivity. The drawback of GUI applications is that they are not as easy to access as Web based applications. For instance a GUI application needs to be installed on each computer where it is to run.
Qt 5 Developments Tools is a package that provides tools for the Qt5 framework. It includes the Qt5 Desginer which is a graphical designer for Qt5 applications.
Both the PyQt5 framework and PyQt5 Tools may be installed within a Python virtual environment. For example the command: virtualenv path-to-project will create a folder with standard Python libraries and binaries. This folder works as an isolated environment within which Python applications can be developed.
The benefit of using virtual environments is that they allow packages to be installed independently of other virtual environments or the system wide packages. Once a virtual environment has been created, it needs to activated using the command: source bin/activate. This will import the necessary environment.
To install the PyQt5 package, we need to run the command: pip install PyQt5. The PyQt5 tools package may be installed with the command: pip install qttools5-dev-tools. To test if the PyQt5 package has been successfully installed, enter the command: import PyQt5 from the Python shell. If the command does not give errors, then the PyQt5 has been successfully installed
Creating PyQt5 applications
Python GUI applications are run in the same way as command line applications. The main difference is that instead of output being shown on the console, a graphical window pops up.
Python applications written using the PyQt5 framework all have the same basic structure. The main steps in writing a PyQt5 application are:
- Import the QtWidgets class using:
from PyQt5 import QtWidgets
- Create an instance of the QMainWindow class using:
app = QtWidgets.QApplication(sys.argv)
Command line arguments are passed to the constructor
- Create an instance of the QMainWindow class using:
MainWindow = QtWidgets.QMainWindow()
This is the actual user interface class
- Create an instance of the Ui_MainWindow class using:
ui = Ui_MainWindow()
This class is used to setup the user interface class created in the previous step. This class is generated by the pyuic5 tool. The pyuic tool is used to generate python code from the user interface class created by the Qt Designer. The code: ui.setupUi(MainWindow) is used to setup the MainWindow class
- The next step is to create an instance of your own class. For example: Ui_Manager. This class is used to setup custom event handlers. The constructor of this class may take the ui object as parameter.
- The next step is to display the window using: MainWindow.show(). This code blocks until the user closes the application.
- The final step is to call: sys.exit(app.exec_()). This will end the application
The GUI related code is usually auto generated using the Qt Desginer and pyuic5. We need to keep our custom code such as event handling code separate from the auto generated GUI code. Otherwise the custom code can get overwritten. The benefit of organizing the code in the way described above is that it separates the GUI related code from the code that implements the application logic. This allows the GUI to be managed using the Qt Desginer, without having to worry about the Qt Desginer overwriting the custom code. The following code shows the "main" function of a typical PyQt5 application:
if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) MainWindow = QtWidgets.QMainWindow() ui = Ui_MainWindow() ui.setupUi(MainWindow) ui_manager = Ui_Manager() ui_manager.initialize_ui(ui); MainWindow.show() sys.exit(app.exec_())
See the source code for the Islam Companion Desktop Reader application on Git Hub for an example of a simple PyQt5 application.
Using the Qt Designer
The Qt Designer allows generating user interface for Qt5 applications. It allows user interfaces to be created by dragging and dropping widgets. It supports several widgets such as ComboBoxes, Lists, Tables, Buttons, Labels and more. It supports four types of layouts which are Horizontal Layout, Vertical Layout, Grid Layout and Form Layout. These layouts allow widgets to be arranged correctly.
Each layout in the Qt Designer is saved in XML format as a separate file with .ui extension. The PyQt5 framework is a wrapper for the Qt5 Framework libraries which are written in C++. The PyQt5 framework provides classes in Python for creating desktop applications. It provides classes for widgets. For example the QApplication class implements the main window class. Classes such as QLabel and QPushButton implement labels and buttons.
Using Python code for arranging widgets can be difficult, since a preview of the user interface is not immediately available. Fortunately the PyQt5 framework contains a tool called pyuic5 which allows converting the .ui files of the Qt Designer to Python code.
For example the command: bin/pyuic5 -x -o MainWindow.py MainWindow.ui will generate the Python file MainWindow.py from the Qt Designer file: MainWindow.ui. The Python file can then be run using the command: python MainWindow.py. This should run the GUI application. The application should look exactly like the preview in the Qt Designer.
Generating executable files using pyqtdeploy
pyqtdeploy is a tool that allows deploying PyQt applications. It supports deploying applications to desktop platforms and mobile platforms. It supports Linux, Windows, MacOs and Android. pyqtdeploy creates a standalone binary file that can be run on the target platform.
pyqtdeploy can be installed as a Python package using the command: pip install pyqtdeploy. It requires the PyQt5 and Python 3.5 and later.
A useful way to learn about pyqtdeploy is to deploy the demo application that is packaged with pyqtdeploy. The demo application is a simple application written using PyQt5 and Python. The documentation for the demo application describes how to build the application on the target platform.
Generating a standalone binary file using pyqtdeploy requires the following steps:
Identify the PyQt modules and other third party components that are required by the application. These components are specified in the sysroot.json file. The sysroot.json file that is provided with the demo application is a good starting point.
The systemroot contains the Python libraries and third part components required by the application. The document Building a System Root Directory describes how to build a sysroot. Building a sysroot can take several hours depending on the components selected. The system root is then built using the command: pyqtdeploy-sysroot --sysroot sysroot-linux-64/ --source-dir lib --verbose sysroot.json. The pyqtdeploy-sysroot command is part of the pyqtdeploy package.
Building a sysroot causes the components specified in sysroot.json to be compiled. Usually qt5, python, sip and pyqt5 are listed in sysroot.json. Compiling qt5 requires certain packages. The article Building Qt 5 from Git describes how to install the dependency packages that are required for building qt5 from source. For example on Ubuntu the dependencies may be installed with the command: sudo apt-get build-dep qt5-default. Note that this command requires source entries in the /etc/apt/sources.list file. Depending on which qt5 features are needed, other dependency packages may need to be installed.
- The next step is to create a project file that identifies the application source code and all the components used by the application. The project file has a .pdy file extension. It can be created using the pyqtdeploy command. This command opens a graphical application that allows generating the project file. For example use the command: pyqtdeploy pyqt-demo.pdy to edit the project file for the demo application. The document Creating a pyqtdeploy Project describes how to create a pyqtdeploy project.
- The next step is to freeze the Python modules and generate a .pro file for qmake. This can be done using the command: pyqtdeploy-build --sysroot sysroot-linux-64/ --verbose pyqt-demo.pdy. The article Building the Application describes how to do generate the .pro file.
- The next step is to generate the MakeFile using the qmake command. This can be done using the command: [path-to-qmake] pyqt-demo.pro. This command should be run from the target build directory which was generated during the previous step. The path-to-qmake is the absolute path to the qmake binary file within the sysroot. Once the MakeFile has been generated, the next step is to generate the executable file using the command: make.