8. GUI库 - PyQt5

本章将简单介绍下PyQt5,首先使用PyQt创建简单桌面应用程序,然后在鲁班猫板卡上使用Qt Creator, 进行简单ui设计,下面的简单示例用于学习参考,更深入学习看下参考资料。

  • 平台:鲁班猫RK系列板卡

  • 系统:Debian10 (带桌面)

  • Python版本:Python3.7

  • Qt版本: 系统默认5.11.3

  • PyQt版本:PyQt5

8.1. PyQt5库简介

PyQt是Qt应用框架与Python的结合,同时支持Python2.x和Python3.x版本,本教程使用的是Python3.7版本,PyQt5版本。

PyQt5是由一系列Python模块组成,超过620个类,6000函数和方法。能在诸如Unix、Windows和Mac OS等主流操作系统上运行,而且由于Python语言的开发方便性,在编写代码时比C++更为方便,美中不足的是Python语言的执行效率会比C++慢。

PyQt5提供GPL版和商业版证书,自由开发者可以使用免费的GPL许可,如果需要将PyQt用于商业应用,则必须购买商业许可。

8.2. PyQt5库安装

8.2.1. Qt库安装

我们使用apt工具安装PyQt5(或者使用pip安装):

# 通过apt工具安装
sudo apt-get -y install python3-pyqt5

# 通过pip安装
pip3 install pyqt5

# qt库安装
sudo apt-get install qt5-default

安装成功后:

cat@lubancat:~$ python3
Python 3.7.3 (default, Oct 31 2022, 14:04:00)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import PyQt5
>>>

接下来我们测试一下PyQt5在鲁班猫板卡上的运行。

重要

在桌面系统中使用,实验前请确保连接桌面屏幕,HDMI或者mipi屏幕都行。

8.3. PyQt5库基础使用

我们将通过一个名字为pyqt5_demo.py的PyQt5应用程序,简单介绍下pyqt5桌面应用程序的编写。 该应用程序主要是用于测试显示、触摸、信号、槽函数、以及PyQt5的部分组件如:QWidget、QLCDNumber、QSlider、QVBoxLayout等的简单使用。

8.3.1. 导入需要模块

# 导入sys模块,包含一些外部向程序传递参数,退出程序,获取系统平台,系统路径等操作
import sys
# 导入QtWidgets模块的一些子模块,QWidget类(用户界面基类),QLCDNumber(展示LCD样式的数字),QSlider(滑动条控件)
# QVBoxLayout(控件垂直布局等)QApplication(管理GUI应用程序的控制流和主设置等)
from PyQt5.QtWidgets import QWidget,QLCDNumber,QSlider,QVBoxLayout,QApplication
# 导入PyQt5.QtCore.Qt,一些基本的函数和类
from PyQt5.QtCore import Qt

# 如果你嫌麻烦,可以替换成 ``*`` ,占用点内存全部导入,例如:
from PyQt5.Qt import *

常用的模块有QtWidgets、QtCore、QtGui等等,其中QtWidgets包括一整套的UI元素控件,用于建立符合系统风格的界面,QtGui模块涵盖了多种基本图形功能的类(字体,图形,图标,颜色), QtCore涵盖了核心的非GUI界面的功能(时间,文件,目录,数据类型,文本流,线程进程等对象)。

8.3.2. 创建一个类将作为主窗口

# 创建一个名为WinForm的类,基于QWidget
class WinForm(QWidget):
        # 初始化类
        def __init__(self):
            # 继承父类的init
            super().__init__()
            # 初始化本身窗口
            self.initUI()

        def initUI(self):
            # 先创建滑块和 LCD 部件
            lcd = QLCDNumber(self)
            slider = QSlider(Qt.Horizontal, self)

            # 设置滑动条最大值和默认值,以及长和宽等,设置默认LCD样式显示数值,
            slider.setMaximum(1000)
            slider.setValue(666)
            slider.setMinimumWidth(200)
            slider.setFixedHeight(60)
            lcd.display(666)

            # 通过QVboxLayout来设置布局,垂直分布
            vBox = QVBoxLayout()
            vBox.addWidget(lcd)
            vBox.addWidget(slider)

            self.setLayout(vBox)
            # valueChanged()是Qslider的一个信号函数,只要slider的值发生改变,它就会发射一个信号,然后通过connect连接信号的接收部件,也就是lcd。
            slider.valueChanged.connect(lcd.display)

            style = "QSlider::groove:horizontal {border:1px solid #999999;height:10px;" \
                    "background-color:#666666;margin:2px 0;}" \
                    "QSlider::handle:horizontal {background-color:#ff0000;border:1px solid #797979;" \
                    "width:50px;margin:-20px;border-radius:25px;}" \

            # 设置样式
            slider.setStyleSheet(style)

            #self.setGeometry(0,0,800,480)
            # 设置窗口标题
            self.setWindowTitle("拖动滑块控制数字显示")

8.3.3. 创建应用程序

# name 是当前模块名, 当模块直接运行时为main,下面的代码块就将运行
if __name__ == '__main__':
    # 每个应用程序需要一个QApplication实例,sys.argv是运行该模块传入命令行参数,可以为空。
    app = QApplication(sys.argv)
    # 控件实例
    form = WinForm()
    # 设置大小,然后显示控件
    form.resize(800, 480)
    form.show()
    # 程序执行,并进入消息事件循环,通过exit函数安全结束
    sys.exit(app.exec_())

创建一个QApplication实例,运行程序,创建一个窗口form,作为主窗口,然后显示。

8.3.4. 整体程序

pyqt5_demo.py整体代码如下:

配套代码libdemo/PyQt5/pyqt5_demo.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import sys
from PyQt5.QtWidgets import QWidget,QLCDNumber,QSlider,QVBoxLayout,QApplication
from PyQt5.QtCore import Qt

class WinForm(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        # 先创建滑块和 LCD 部件
        lcd = QLCDNumber(self)
        slider = QSlider(Qt.Horizontal, self)

        slider.setMaximum(1000)
        slider.setValue(666)
        slider.setMinimumWidth(200)
        slider.setFixedHeight(60)
        lcd.display(666)

        # 通过QVboxLayout来设置布局
        vBox = QVBoxLayout()
        vBox.addWidget(lcd)
        vBox.addWidget(slider)

        self.setLayout(vBox)
        # valueChanged()是Qslider的一个信号函数,只要slider的值发生改变,它就会发射一个信号,然后通过connect连接信号的接收部件,也就是lcd。
        slider.valueChanged.connect(lcd.display)

        style = "QSlider::groove:horizontal {border:1px solid #999999;height:10px;" \
                "background-color:#666666;margin:2px 0;}" \
                "QSlider::handle:horizontal {background-color:#ff0000;border:1px solid #797979;" \
                "width:50px;margin:-20px;border-radius:25px;}" \

        slider.setStyleSheet(style)
        #self.setGeometry(0,0,800,480)
        self.setWindowTitle("拖动滑块控制数字显示")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    form = WinForm()
    form.resize(800, 480)
    form.show()
    sys.exit(app.exec_())

终端直接运行我们的pyqt5_demo.py程序:

sudo python3 pyqt5_demo.py

显示效果:

pyqt5_001

大家可以将配套代码目录 libdemo\PyQt5\pyqt5_demo.py,上传到开发板中测试。

8.4. Qt Designer使用

一般情况下,我们自己用python程序创建自己的界面应用,但随着应用程序越来越大或界面越来越复杂,以编程方式定义所有窗口部件可能会很麻烦。 这个情况下可以使用Qt Designer专门来制作PyQt程序中UI界面,下面将介绍下使用Qt Designer创建一个简单的登录UI界面。

# 通过apt安装Qt Creator工具
sudo apt install qtcreator

# 安装qt designer等工具
sudo apt install qttools5-dev-tools

重要

在鲁班猫中使用Qt Creator,设计一些复杂界面时会卡住或者直接卡死,可能是内存不够,建议在虚拟机或者PC中设计ui或者编写pyqt5程序,可以在板卡上直接运行。

安装之后,可以在桌面菜单搜索Qt Creator,或者直接打开Qt Designer,然后打开应用:

pyqt5_001

8.4.1. 创建一个界面UI文件

打开Qt Creator后点击file ,选择go to File -> New File or Project,在 Files and Classes 栏,点击 QT ,选中 QT Designer Form , 之后设置创建的.ui文件名字,路径等,如下:

broken

接着选择 Main Window 或者其他,最后设置文件路径和文件名即可:

broken

8.4.2. 界面构建

在ui界面,添加一个容器Frame放到画布上,并调整大小。创建一个简单的登录界面,需要账号密码栏,使用Input Widgets:Line Edit, 登录和取消使用按钮Buttons:PushButton,忘记密码框就用文本栏Display Widgets:TextLabe,记住密码使用Buttons:CheckBox,把这些控件拖到窗口,设置下名称,布局如下:

broken

设置样式,右击整个容器,选择 edit style sheel ,填入下面代码,自己可以根据喜好更改颜色、样式和选择背景图片路径,这简单配置了下,看起来还行~:

*{
background:rgb(0, 0, 0);
font-size:15px;
font-style:MingLiU-ExtB;
}
QFrame{
border:sold 10px rgba(255,255,255);
background-image:url(/home/cat/qt/login/lubancat6.png);
}
QLineEdit{
color:#8d98a1;
background-color:rgb(0, 0, 0);
font-size:16px;
border-style:outset;
border-radius:10px;
font-style:MingLiU-ExtB;
}
QPushButton{
background:#ced1d8;
border-style:outset;
border-radius:10px;
font-style:MingLiU-ExtB;
}
QPushButton:pressed{
background-color:#405361;
border-style:inset;
font-style:MingLiU-ExtB;
}
QCheckBox{
background:rgba(85,170,255,0);
color:white;
font-style:MingLiU-ExtB;
}
QLabel{
background:rgba(85,170,255,0);
color:white;
font-style:MingLiU-ExtB;
font-size:14px;
}
broken

提示

ui的设计,以及qt designer使用,可以参考下Qt相关的教程。

8.4.3. 调用ui文件

使用qt designer设计的.ui文件,可以直接使用uic模块导入ui文件,或者把.ui文件转换成python模块,直接导入使用。

  1. 直接使用uic模块导入.ui文件:

配套代码libdemo/PyQt5/login/login.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5 import uic

class LoginWindow(QMainWindow):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 使用uic.loadUi导入当前目录下的.ui文件
        uic.loadUi("login.ui", self)
        self.setWindowTitle("Lubancat login")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = LoginWindow()
    window.show()
    sys.exit(app.exec_())
  1. 或者转换成python文件导入

使用pyuic5命令将.ui文件转换成python文件:

# 通过apt安装pyqt5-dev-tools工具
sudo apt-get install pyqt5-dev-tools

# 使用命令将.ui文件转换成python文件
pyuic5 -o login.ui login_ui.py

转换成python文件,可以直接导入使用:

配套代码libdemo/PyQt5/login/login_ui_form.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
# 导入转换出的Ui_Form类
from login_ui  import Ui_Form

class LoginWindow(QMainWindow):

    def __init__(self, parent=None):
        super().__init__(parent)
        # 创建一个ui实例
        self.ui = Ui_Form()
        # 运行setupUi()显示ui
        self.ui.setupUi(self)
        self.setWindowTitle("Lubancat login")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = LoginWindow()
    win.show()
    sys.exit(app.exec())

运行程序,可以在终端使用命令:

# 使用命令运行程序:
sudo python3 login.py

或者在Qt Creator添加一个python运行环境,需要点击界面的 Tool->Options... 在弹窗的界面选择 Enviroment ,然后按下面图片操作,最后点击 apply 应用。

broken

运行时,打开对应python文件,然后点击 Tool->Exteral->RunPython->RunPy 即可。

运行显示效果:

broken

程序源码参考下配套例程libdemo/PyQt5目录中文件,最后如果需要打包发布你的应用程序,可以看下参考链接的一些文档。