Super complete! Python graphical interface framework PyQt5 usage guide!

Super complete! Python graphical interface framework PyQt5 usage guide!

  • Preface
  • 1. Common GUI frameworks
  • 2. Introduction to PyQt5
  • 3. Installation of PyQt5
  • 4. Qt Designer configuration
  • 5. PyQt5 actual combat

Foreword

There are actually not many softwares that use Python to develop graphical interfaces. Compared with GUI interfaces, Web applications may be more popular. But for people like me who are not familiar with other programming languages such as C# or WPF, it may not be a good tool.

1. Common GUI frameworks

PyQt5: Qt is a cross-platform C++ graphical user interface library. QT was once owned by Nokia and later sold to Digia Oyj, a Finnish software company. PyQt5 is a Python interface based on Digia’s Qt5 and consists of a set of Python modules. PyQt5 itself has more than 620 classes and 6000 functions and methods. Can run on multiple platforms, including: Unix, Windows, and Mac OS.

Pyside6: Pyside is the Python package officially provided by QT Company. The previous version was Pyside2, which corresponds to QT5. The naming rules of the latest version have been adjusted and changed to Pyside6, which corresponds to QT6 version. Since the official product is relatively promising, the disadvantage is that it was released late and there is not as much information on the Internet as PyQt5.

Tkinter: Python’s built-in GUI framework is implemented using TCL. The TCL interpreter is embedded in Python. When using it, you don’t need to install additional extension packages. It can be imported directly and is cross-platform. The disadvantage is that the UI layout is entirely implemented by code, there are only 15 common components, and the display effect is simple.

PySimpleGUI: PySimpleGUI is a wrapper for Tkinter. Implementing a custom GUI using PySimpleGUI requires much less code than writing the same GUI directly using Tkinter.

WxPython: wxPython is a Python language binding for the popular wxWidgets cross-platform GUI tool library. It is widely used, cross-platform, written in C++, and has few documents. Users may need to make some adjustments to the GUI code in different platforms based on the programming content. It is difficult to solve problems when encountering them. The code layout control is not intuitive.

Wax: Based on wxPython, a package made to overcome the problems of wxPython.

Kivy: Mainly for multi-touch programs, smartphones and tablets, etc. It can also be used on systems without touch screen functions, supporting all platforms (Windows, Linux, Mac OS X, Android and iOS.) Written in Python and cython, Chinese support is poor. You need to download the Chinese library yourself and formulate the path.

BeeWare: Write once. Deploy everywhere. Needs to be used with Kivy.

Toga: A GUI toolkit for developing native APPs using Python. Toga consists of a base component library with shared interfaces to simplify platform-independent GUI development. Toga is available for Mac OS, Windows, Linux (GTK), and mobile platforms such as Android and iOS.

Eel: A lightweight Python library for making simple offline HTML/JS GUI applications similar to Electron (but more lightweight than it), with Python capabilities and Full access to the library.

Flexx: A pure Python toolkit for creating graphical interface applications. It uses web technology for interface rendering. You can use Flexx to create desktop applications, and you can also export an application to a standalone HTML document. Because it is developed in pure Python, Flexx is cross-platform. All you need is Python and a browser to run.

pywebview is a lightweight cross-platform wrapper around the webview component that allows HTML content to be displayed in its own native GUI window. It allows you to use web technologies in desktop applications while hiding as much as possible the fact that a browser is used to build the GUI.

enaml: A Python framework that allows you to implement high-quality GUI interfaces with minimal effort. It is also a unique programming language. enaml combines a declarative language with a constraint-based layout system, allowing users to easily define flexible layouts of UI. enaml applications can run on any platform that supports Python and Qt.

Personal thoughts: There is too much to learn, so learn PyQt5 first because there is a lot of information, and then learn pyside6 if you have enough energy. Finally, take a look at PySimpleGUI to see if you can solve some simple problems.

2. Introduction to PyQt5

PyQt is a Python language implementation of the Qt framework. It was developed by Riverbank Computing and is one of the most powerful GUI libraries. PyQt provides a well-designed collection of window controls. Each PyQt control corresponds to a Qt control, so PyQt’s API interface is very close to Qt’s API interface, but PyQt no longer uses the QMake system and the Q_OBJECT macro.

PyQt5 provides GPL version and commercial version certificates. Free developers can use the free GPL license. If you need to use PyQt for commercial applications, you must purchase a commercial license.

PyQt5 features are as follows:

· High-performance Qt-based GUI control set.
· Able to run cross-platform on Linux, Window and Mac OS systems.
· Use signals and slots mechanism for communication.
· Completely encapsulate the Qt library.
· You can use a mature IDE for interface design and automatically generate executable Python code.
· Provides a complete set of window controls.
· PyQt5 is composed of a series of Python modules, with more than 620 classes, 6000 functions and methods. The main modules are as follows:
· QtCore: Contains core non-GUI functionality. Mainly used with time, files and folders, various data, streams, URLs, mime class files, processes and threads.
· QtGui: includes window system, event handling, 2D images, basic painting, fonts and text classes.
· QtWidgets: Contains a series of UI elements for creating desktop applications.
· QtMultimedia: Contains classes for processing multimedia content and calling the camera API.
· QtBluetooth: Contains classes for finding and connecting to Bluetooth.
· QtNetwork: Contains classes for network programming. These tools make TCP/IP and UDP development more convenient and reliable.
· QtPositioning: Contains classes for positioning, which can use satellite, WiFi or even text.
· Enginio: Contains classes for entering and managing Qt Cloud through the client.
· QtWebSockets: A class that contains the WebSocket protocol.
· QtWebKit: Contains a web browser based on WebKit2.
· QtWebKitWidgets: Contains WebKit1 classes based on QtWidgets.
· QtXml: Contains classes for processing xml and provides tools for SAX and DOM APIs.
· QtSvg: Provides classes for displaying SVG content. Scalable Vector Graphics (SVG) is a graphics format based on Extensible Markup Language (XML) for describing two-dimensional vector graphics (this sentence comes from Wikipedia ).
· QtSql: Provides tools for working with databases.
· QtTest: Provides tools for testing PyQt5 applications.

3. Installation of PyQt5

Since fbs will be used for packaging later, fbs may have compatibility issues with Python 3.7 and later versions, so I chose Python 3.6.8 to build the entire environment. The main content is: Python + PyCharm + PyQt5

Install PyQt5

pip install pyqt5

pip install pyqt5-tools

Among them, pyqt5-tools is Qt Designer’s drag-and-drop interface design tool. The following error may be reported during the installation process:

qt5-tools 5.15.2.1.2 has requirement click~=7.0, but you'll have click 8.0.1 which is incompatible.

solution:

pip install click~=7.0

4. Qt Designer configuration

Qt Designer uses drag and drop to place controls and view the control effects in real time for quick UI design.

The composition of the entire picture:

·The “Widget Box” on the left is a variety of components that can be freely dragged
·The “MainWindow – untitled” form in the middle is the canvas
·The “Object Inspector” on the upper right can view the structure of the current ui
·The “Property Editor” in the middle right can set the properties of the currently selected component
·The “Resource Browser” on the lower right can add various materials, such as pictures, backgrounds, etc.

Finally, a .ui file (essentially a file in XML format) is generated, which can be used directly or converted into a .py file through the pyuic5 tool.

QtDissigner configuration
In Pycharm, open File – Settings – Tools – External Tools, click + Create Tool, and configure as follows:

Name: QtDissigner

Program: D:\Program Files\Python36\Lib\site-packages\qt5_applications\Qt\bin\designer.exe # Please modify according to actual situation

Working directory: $FileDir$

PyUIC configuration

PyUIC mainly replaces the .ui files generated by Qt Designer with .py files.

In Pycharm, open File – Settings – Tools – External Tools, click + Create Tool, and configure as follows:

Name: PyUIC

Program: D:\Program Files\Python36\python.exe # Current Python directory, please modify it according to actual situation

Arguments: -m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py

Working directory: $FileDir$

PyRCC configuration

PyRCC mainly replaces the written .qrc resource files with .py files. In Pycharm, open File – Settings – Tools – External Tools, click + Create Tool, and configure as follows:

Name: PyRCC

Program: D:\Program Files\Python36\pyrcc5.exe # Current rcc tool directory, please modify it according to actual situation

Arguments: $FileName$ -o $FileNameWithoutExtension$_rc.py

Working directory: $FileDir$

PyQt5 usage example

Create a blank interface:

import sys

from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel

app = QApplication(sys.argv)

win = QMainWindow()

win.setGeometry(400, 400, 400, 300)

win.setWindowTitle("Pyqt5 Tutorial")

win.show()

sys.exit(app.exec_())


in:

·Qapplication(): Each GUI must contain a Qapplication. argv means to obtain the command line parameters. If you do not need to obtain them, you can use [] instead.

·QMainWindow(): Similar to a container (window) used to contain widgets such as buttons, text, and input boxes. The arg flag can obtain the parameters when executing the command line.

·SetGeometry is used to define the size of the QMainWindow() window. Syntax: setGeometry(x, y, width, height), where x, y are the coordinate points on the screen.

·show(): used to display the window

·exit(app.exec_()): Set the window to keep running and guide you to use the close button to close it

Common Widgets supported by PyQt5 are:


From top to bottom, from left to right: Qlabel, QcomboBox, QcheckBox, QradioButton, QpushButton, QtableWidget, QlineEdit, Qslider, QProgressBar

For setting text content using Pyqt5, we use Qlabel:

import sys

from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel

app = QApplication(sys.argv)

win = QMainWindow()

win.setGeometry(400, 400, 400, 300)

win.setWindowTitle("Pyqt5 Tutorial")

\# Label Text

label = QLabel(win)

label.resize(200, 100)

label.setText("Hi this is Pyqt5")

label.move(100, 100)

win.show()

sys.exit(app.exec_())


Buttons and Events:

import sys

from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton

def click():

    print("Hy Button is clicked!")

app = QApplication(sys.argv)

win = QMainWindow()

win.setGeometry(400, 400, 400, 300)

win.setWindowTitle("Pyqt5 Tutorial")

\# Button

button = QPushButton(win)

button.resize(200, 100)

button.setText("Hi! Click Me")

button.move(100, 100)

button.clicked.connect(click)

win.show()

sys.exit(app.exec_())

button.clicked.connect() executes a specific event after the button is clicked.

5. PyQt5 in practice

Practical project: Simple weather query software

1. Use Qt Designer to design an interface

The controls used include Button, GroupBox, Label, ComboBox, and TextEdit. Two buttons, queryBtn and clearBtn, are defined at the same time, which are used to query and clear weather data respectively. We need to bind the slot function as follows:

· Select the Signal/Slot Editor in the lower right corner of Qt Designer and click the + sign to add

· Select queryBtn and clearBtn respectively, select the signal clicked(), the receiver Dialog and the slot accept() (I don’t know how to define the slot function here, I will modify it in the code later)

After the above is completed, save it as a Weather.ui file.

2. Convert .ui files to .py files

PyQt5 supports using .ui files directly:

import sys

from PyQt5 import QtWidgets, uic

app = QtWidgets.QApplication(sys.argv)

window = uic.loadUi("mainwindow.ui")

window.show()

app.exec()

However, in order to better customize and modify the above slot function, you can use External Tools – PyUIC to generate Weather.py. The actual running command is as follows:

D:\Program Files\Python36\python.exe -m PyQt5.uic.pyuic Weather.ui -o Weather.py

Among them, we need to bind the two button slot functions:

\# self.queryBtn.clicked.connect(Dialog.accept)

\# self.clearBtn.clicked.connect(Dialog.accept)

\# change into:

self.queryBtn.clicked.connect(Dialog.queryWeather)

self.clearBtn.clicked.connect(Dialog.clearText)

The final Weather.py content is as follows:

\# -*- coding: utf-8 -*-

\# Form implementation generated from reading ui file 'Weather.ui'

\#

\# Created by: PyQt5 UI code generator 5.15.4

\#

\# WARNING: Any manual changes made to this file will be lost when pyuic5 is

\# run again. Do not edit this file unless you know what you are doing.

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_Dialog(object):

    def setupUi(self, Dialog):

        Dialog.setObjectName("Dialog")

        Dialog.resize(600, 600)

        self.groupBox = QtWidgets.QGroupBox(Dialog)

        self.groupBox.setGeometry(QtCore.QRect(30, 20, 551, 511))

        self.groupBox.setObjectName("groupBox")

        self.label_2 = QtWidgets.QLabel(self.groupBox)

        self.label_2.setGeometry(QtCore.QRect(20, 30, 31, 16))

        self.label_2.setObjectName("label_2")

        self.comboBox = QtWidgets.QComboBox(self.groupBox)

        self.comboBox.setGeometry(QtCore.QRect(70, 30, 87, 22))

        self.comboBox.setObjectName("comboBox")

        self.comboBox.addItem("")

        self.comboBox.addItem("")

        self.comboBox.addItem("")

        self.textEdit = QtWidgets.QTextEdit(self.groupBox)

        self.textEdit.setGeometry(QtCore.QRect(20, 70, 491, 411))

        self.textEdit.setObjectName("textEdit")

        self.queryBtn = QtWidgets.QPushButton(Dialog)

        self.queryBtn.setGeometry(QtCore.QRect(490, 560, 93, 28))

        self.queryBtn.setObjectName("queryBtn")

        self.clearBtn = QtWidgets.QPushButton(Dialog)

        self.clearBtn.setGeometry(QtCore.QRect(30, 560, 93, 28))

        self.clearBtn.setObjectName("clearBtn")

        self.retranslateUi(Dialog)

        self.clearBtn.clicked.connect(Dialog.clearText)

        self.queryBtn.clicked.connect(Dialog.queryWeather)

        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):

        _translate = QtCore.QCoreApplication.translate

        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))

        self.groupBox.setTitle(_translate("Dialog", "City Weather Forecast"))

        self.label_2.setText(_translate("Dialog", "City"))

        self.comboBox.setItemText(0, _translate("Dialog", "Beijing"))

        self.comboBox.setItemText(1, _translate("Dialog", "Suzhou"))

        self.comboBox.setItemText(2, _translate("Dialog", "Shanghai"))

        self.queryBtn.setText(_translate("Dialog", "Query"))

        self.clearBtn.setText(_translate("Dialog", "Clear"))

3. Call MainDialog
Call the interface class Ui_Dialog in MainDialog, and then add the business logic code for weather query in it, thus achieving the separation of interface display and business logic. Add a new demo.py file and define two slot functions queryWeather() and clearText() in the MainDialog class so that the two buttons (queryBtn and clearBtn) defined in the interface file Weather.ui can trigger the clicked signal with these two slot function for binding.

The complete code is as follows:

import sys

import Weather

from PyQt5.QtWidgets import QApplication, QDialog

import requests

class MainDialog(QDialog):

    def __init__(self, parent=None):

        super(QDialog, self).__init__(parent)

        self.ui = Weather.Ui_Dialog()

        self.ui.setupUi(self)

    def queryWeather(self):

        cityName = self.ui.comboBox.currentText()

        cityCode = self.getCode(cityName)

        r = requests.get(

            "https://restapi.amap.com/v3/weather/weatherInfo?key=f4fd5b287b6d7d51a3c60fee24e42002 & amp;city={}".format(

                cityCode))

        if r.status_code == 200:

            data = r.json()['lives'][0]

            weatherMsg = 'City: {}\\
Weather: {}\\
Temperature: {}\\
Wind direction: {}\\
Wind force: {}\\
Humidity: {}\\
Release time: { }\\
'.format(

                data['city'],

                data['weather'],

                data['temperature'],

                data['winddirection'],

                data['windpower'],

                data['humidity'],

                data['reporttime'],

            )

        else:

            weatherMsg = 'Weather query failed, please try again later! '

        self.ui.textEdit.setText(weatherMsg)

    def getCode(self, cityName):

        cityDict = {<!-- -->"Beijing": "110000",

                    "Suzhou": "320500",

                    "Shanghai": "310000"}

        **return** cityDict.get(cityName, '101010100')

    def clearText(self):

        self.ui.textEdit.clear()

if __name__ == '__main__':

    myapp = QApplication(sys.argv)

    myDlg = MainDialog()

    myDlg.show()

    sys.exit(myapp.exec_())

The effect after running demo.py and executing the query:


4. Package the code into an exe file
Packaging a .py file into an executable exe is called freezing in Python. Commonly used tools include: PyInstaller, py2exe, cx_Freeze, bbfreze, py2app, etc. Function comparison:


py2exe: Software updates are no longer active and therefore skipped.

pyinstaller: It clearly supports win8, win10, theoretically supports win7, and supports apple Macos and linux. pyinsaller can be packaged into a folder containing an exe entry execution file, or it can be a separate exe file.

fbs: Based on PyInstaller, it is more convenient to use

Here fbs is chosen for packaging. How to install fbs:

pip install fbs

To use, enter in the command line:

fbs startproject

After the execution is completed, you need to enter some APP names, etc. After completion, the following directory will be generated:


Drag the PyQt5 code (demo.py and Weather.py) you just wrote to the src/main/python folder, delete the original main.py, and change demo.py to main.py. Then open main.py and add the following code to the head of the file:

from fbs_runtime.application_context.PyQt5 import ApplicationContext

After completion execute:

fbs freeze

Packaging can be achieved. The generated exe executable file is under the \target\MyApp file.