PyQt complete tutorial

1. Introduction to GUI development framework

In the past 19 years, we have been doing Android ROM related tests and accumulated a certain amount; in the past 20 years, we plan to integrate and reuse the previous complete test schemes, scripts and tools.
The first phase of the project is to develop a GUI testing tool, which has been investigated recently.

1.1 general development framework

  • electorn: Based on node JS, cross platform, low development cost and low operation efficiency
  • qt: Based on C + +, cross platform, high efficiency, high development cost
  • javafx: Based on java, mainly used for cross platform desktop program development
  • Flitter: Based on dart language, Google's open source mobile UI framework can quickly build high-quality native user interface on iOS and Android

1.2 Python solution

  • PyQT: PyQt5 is the Python version of Qt v5, with powerful and complex functions. It provides QT Designer design UI (GPL V3 protocol, open source, commercial charges)
  • Pside: pside2 is the official Python module from QT for Python project (LGPL protocol, closed source commercial)
  • Tkinter: Python standard library, interface of Tk GUI toolkit, layout realized by code, simple and easy to use, but low development efficiency
  • WxPython: open source and free, providing wxform builder, compressed PyQT

Because most of the existing scripts are developed based on Python, at the same time, we have investigated the official support of the above framework and the richness of network data, and finally chose the most popular and powerful one PyQt .

This article mainly introduces the PyQt5 complete tutorial in detail, including environment configuration, using QT discinger to design UI, and finally completing a GUI instance development of weather forecast.

Environment: Windows 10 + Python 3.8 + PyCharm 2019.2

2. PyQt environment configuration

2.1 PyQt5 and pyqt5 tools installation

The latest version of PyQt is PyQt5 5.14.1

Direct pip installation:

pip install PyQt5
pip install pyqt5-tools

It is recommended to use domestic sources for quick installation:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyqt5
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyqt5-tools

2.2 PyCharm configuration environment

After starting PyCharm and creating a new PyQt5 empty project, you need to configure Qt Designer, pyuic, and pyrcc tools. The related configuration methods are as follows:

2.2.1 Qt Designer

Qt Designer is to place the control by dragging, and view the control effect in real time for rapid UI design.

Finally. ui files (essentially XML format files) are generated, which can be converted into. py files through pyuic5 tools.

In Pycharm, open File - Settings - Tools - External Tools, click + Create Tool, and the configuration is as follows:

Name: QtDisigner
Program : C:\Python38\Lib\site-packages\pyqt5_tools\Qt\bin\designer.exe # Please modify the current designer directory according to the actual situation
Working directory: $FileDir$

2.2.2 Qt Designer localization

By default, Qt Designer is in English, which can be translated into Chinese. Download address: Baidu SkyDrive , extraction code: kxvx

After downloading the file designer, copy it to the translation folder of local pyqt5 tools. Example Directory:

C:\Python38\Lib\site-packages\pyqt5_tools\Qt\bin\translations

In PyCharm main interface, click Tools - external tools - qtdispatcher to start QT dispatcher in Chinese interface

2.2.3 PyUIC configuration

PyUIC mainly changes the. ui file generated by Qt Designer into. py file.

In Pycharm, open File - Settings - Tools - External Tools, click + Create Tool, and the configuration is as follows:

Name: PyUIC
Program : C:\Python38\python.exe # The current Python directory, please modify according to the actual situation
Arguments: -m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py
Working directory: $FileDir$

2.2.4 PyRCC configuration

PyRCC mainly changes the. qrc resource file into. py file.

In Pycharm, open File - Settings - Tools - External Tools, click + Create Tool, and the configuration is as follows:

Name: PyRCC
Program : C:\Python38\Scripts\pyrcc5.exe # Please modify the current rcc tool directory according to the actual situation
Arguments: $FileName$ -o $FileNameWithoutExtension$_rc.py
Working directory: $FileDir$

3. Case development

Let's take a simple urban weather forecast as an example to demonstrate the basic process of developing a GUI program with PyQt5.

3.1 obtaining weather data

The main logic is to call the free API interface through Http interface to obtain the relevant city weather data. See details Weather API description

For example, to test the weather in Tianjin, the link is: http://t.weather.sojson.com/api/weather/city/101030100

The status returned is 200, the failure is not 200, and the returned data is json data, which can be obtained directly by parsing.

3.1 design interface UI

Open Qt Designer, and refer to the following figure to design Weather.ui:

The main controls we use are Button, GroupBox, Label,ComboBox,TextEdit. At the same time, we define two buttons, queryBtn and clearBtn, which are used to query and empty weather data respectively. We need to bind the slot function as follows:

1) Select the signal / slot editor in the lower right corner of Qt Designer, and click + to add
2) Select queryBtn and clearBtn respectively, select the signal clicked(), receiver Dialog and slot accept() (I didn't find the method to bind the custom slot function...)

Finally, choose to save as a Weather.ui file.

3.2 convert. ui file to. py file

Select the Weather.ui file in PyCharm, right-click and select External Tools - PyUIC to generate Weather.py. The actual running command is as follows:

C:\Python38\python.exe -m PyQt5.uic.pyuic Weather.ui -o Weather.py

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

        self.queryBtn.clicked.connect(Dialog.accept)
        self.clearBtn.clicked.connect(Dialog.accept)

Modify to a custom function:

        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.13.2
#
# WARNING! All changes made in this file will be lost!


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(400, 300)
        self.groupBox = QtWidgets.QGroupBox(Dialog)
        self.groupBox.setGeometry(QtCore.QRect(0, 0, 391, 241))
        self.groupBox.setObjectName("groupBox")
        self.textEdit = QtWidgets.QTextEdit(self.groupBox)
        self.textEdit.setGeometry(QtCore.QRect(20, 50, 351, 181))
        self.textEdit.setObjectName("textEdit")
        self.comboBox = QtWidgets.QComboBox(self.groupBox)
        self.comboBox.setGeometry(QtCore.QRect(100, 20, 91, 20))
        self.comboBox.setObjectName("comboBox")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.label = QtWidgets.QLabel(self.groupBox)
        self.label.setGeometry(QtCore.QRect(30, 20, 61, 21))
        self.label.setObjectName("label")
        self.queryBtn = QtWidgets.QPushButton(Dialog)
        self.queryBtn.setGeometry(QtCore.QRect(40, 250, 75, 23))
        self.queryBtn.setMaximumSize(QtCore.QSize(75, 16777215))
        self.queryBtn.setObjectName("queryBtn")
        self.clearBtn = QtWidgets.QPushButton(Dialog)
        self.clearBtn.setGeometry(QtCore.QRect(250, 250, 75, 23))
        self.clearBtn.setMaximumSize(QtCore.QSize(75, 16777215))
        self.clearBtn.setObjectName("clearBtn")
        
        self.retranslateUi(Dialog)
        self.queryBtn.clicked.connect(Dialog.queryWeather)
        self.clearBtn.clicked.connect(Dialog.clearText)
        QtCore.QMetaObject.connectSlotsByName(Dialog)
    
    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.groupBox.setTitle(_translate("Dialog", "Urban weather forecast"))
        self.comboBox.setItemText(0, _translate("Dialog", "Beijing"))
        self.comboBox.setItemText(1, _translate("Dialog", "Shanghai"))
        self.comboBox.setItemText(2, _translate("Dialog", "Tianjin"))
        self.label.setText(_translate("Dialog", "City"))
        self.queryBtn.setText(_translate("Dialog", "query"))
        self.clearBtn.setText(_translate("Dialog", "empty"))

3.3 call MainDialog

In the MainDialog, we call the interface class Ui_Dialog, and then add the business logic code to query the weather, so that the interface display and business logic are separated.

Add the 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 trigger the clicked signal to bind with these two slot functions.

The complete code is as follows:

# coding:utf-8

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("http://t.weather.sojson.com/api/weather/city/{}".format(cityCode))
        
        print(r.json())
        
        if r.json().get('status') == 200:
            weatherMsg = 'City:{}\n Date:{}\n Weather:{}\nPM 2.5: {} {}\n Temperature:{}\n Humidity:{}\n Wind force:{}\n\n{}'.format(
                r.json()['cityInfo']['city'],
                r.json()['data']['forecast'][0]['ymd'],
                r.json()['data']['forecast'][0]['type'],
                int(r.json()['data']['pm25']),
                r.json()['data']['quality'],
                r.json()['data']['wendu'],
                r.json()['data']['shidu'],
                r.json()['data']['forecast'][0]['fl'],
                r.json()['data']['forecast'][0]['notice'],
            )
        else:
            weatherMsg = 'Weather query failed, please try again later!'
        
        self.ui.textEdit.setText(weatherMsg)
    
    def getCode(self, cityName):
        cityDict = {"Beijing": "101010100",
                    "Shanghai": "101020100",
                    "Tianjin": "101030100"}
        
        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 final operation display effect is as follows:

Full demo address: https://github.com/lovesoo/test_demo/tree/master/PyQt5

4. References

  1. https://www.riverbankcomputing.com/static/Docs/PyQt5/

  2. http://code.py40.com/face

  3. PyQt5 rapid development and Practice PDF SkyDrive address Extraction code: k3xx

Tags: Python Qt JSON Pycharm

Posted on Fri, 13 Mar 2020 21:45:33 -0700 by datona