PyQt简介

PyQt 是创建 GUI 应用程序的一个工具包,融合了 Python 和 Qt 库,是 Python 中 GUI 设计最强大的库之一,具有界面美观、跨平台、文档教程多等优点。

PyQt 有功能丰富函数和方法,基本上能够实现绝大部分设计要求;但正是因为此,其功能复杂,接口繁多,学习成本较高。

PyQt 的主要模块有:

  • QtGui:涵盖了多种基本图形的功能的类
  • QtWidgets:包含整套的 UI 元素控件
  • QtCore:涵盖了核心的非 GUI 功能,可用来处理时间、文件、目录、数据类型、文本流、链接等对象

刚开始上手 PyQt 的时候,画控件成为了很令人头疼的问题,使用代码进行控件布局绘制和调整非常不直观,比较费时间。后来发现了简单的控件绘制工具——Qt Designer。Qt Designer 是交互式可视化 GUI 设计工具,可以帮助我们快速绘制 UI 界面。

下面就以我开发的一个用来测试 TDCP 和 TUMS 接口的小程序为例,介绍 PyQt 的开发流程。

Qt Designer

安装

安装 PyQt5 和 QtDesigner

pip install PyQt5
pip install PyQt5-tools

安装完后,Qt Designer 的路径为:Python安装路径\Lib\site-packages\qt5_applications\Qt\bin\designer.exe

UI 设计

启动后,首先新建一个 Widget

然后将左侧 Widget Box 中的控件按照个人设计拖拽到打开的窗口中,自行修改大小和布局,双击修改名称,并且可以在右侧的属性编辑器中根据需要修改属性(仿佛回到了高中信息技术课上学 VB)。

设计过程中,使用快捷键 Ctrl-R 可以快速预览。

我设计完的页面如下:

转化为 py 文件

完成设计后,保存输出的文件是 .ui 格式的,可以使用 PyUIC 工具转为 .py 文件:

pyuic5 -o 目标文件名.py 源文件名.ui

程序设计

基本框架

上述 ui 文件转化完的 py 文件中,仅有一个Ui_Form的类,包含setupUiretranslateUi两个方法,没有程序入口,并不能直接运行。

按照视图与逻辑分离的原则,我们再编写一个新的类来调用这个方法。

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5 import QtCore, QtWidgets


class Ui_Form(object):
	...


class MyWindow(QMainWindow, Ui_Form):
	def __init__(self):
        QMainWindow.__init__(self)
        self.setupUi(self)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MyWindow()
    window.show()
    sys.exit(app.exec_())

此时,运行该脚本就会出现我们绘制的 UI 窗口了:

UI调整

由于界面上显示的各类元素本质上都在 python 代码中定义和实现,所以我们可以在代码中对其进行调整,比如修改程序的标题,只需要在retranslateUi方法中修改一行代码:

Form.setWindowTitle(_translate("Form", "简易发包工具For TUMS/TDCP"))

控件逻辑添加

上述我们完成的部分只是一个 UI 界面,并没有任何功能,因此,我们还需要在程序中为各类控件添加逻辑,才能实现我们想要的功能。

下面列举一些常用的方法:

  • 将点击按钮绑定到某一方法

    pushButton.clicked.connect(method_name)
    
    def method_name():
    	...
    
  • 获取输入框内容

    line = lineEdit.text()
    text = textEdit.toPlainText()
    
  • 设置文本输入框内容

    textEdit.setText(text)
    

至于如何将各类控件逻辑组合起来,实现完整的功能,属于 python 程序设计的部分,在此不做说明。

打包与发布

使用 pyinstaller 进行打包,可以把源文件打包成 exe 文件,这样使用时不用依赖 python 环境,可以直接拷贝 exe 文件到其他 Windows PC 上使用。

打包方法

先安装 pyinstaller:

pip install pywin32
pip install pyinstaller

然后使用 pyinstaller 打包

pyinstaller -F -w postTool.py

完成后,会在当前目录下生成一个 spec 文件和builddist两个文件夹,可执行的 exe 文件就在dist文件夹中,双击即可运行。

在此提供我写的小工具主程序部分代码和可执行 exe 文件:

发送 TDCP/TUMS 请求部分由于涉及到相关登录校验规则,在此不提供。

缺陷

使用 pyinstaller 打包会把各种依赖库都一起打包进去,导致生成的 exe 文件很大,且启动速度很慢。我写完的程序打包好占用接近 35 MB,启动大约需要 5 秒。

尝试过各种优化方式,比如建立 python 虚拟环境减少打包依赖、换用其他打包方式等,效果都不明显。而在测试部广泛使用的 Windows 小程序postData.exe(基于 MFC 开发),同样用来发送 TDCP 请求,大小只有 100 K,且启动很快。

MFC 是微软提供的一个 C++ 类库

由此体会到 Python 的局限性还是很大啊。

后续

最近因为装的 Python 库越来越多,导致新开发的 PyQt GUI 工具打包越来越大,所以还是用虚拟环境打包吧,补充一下虚拟环境打包方法:

  1. 安装 virtualenvs
pip install virtualenv
  1. 进入项目根路径,创建虚拟环境
virtualenv venv
  1. 激活虚拟环境
cd venv/Scripts
activate

执行完后,可以看到命令行名称前出现了(venv),说明虚拟环境激活成功
4. 安装项目依赖库
因为新激活的虚拟环境不包含任何依赖库,所以需要先手动将该工具项目所需要的依赖安装一下,直接用pip安装即可,装完之后手动执行一下python xxx.py看看能不能运行
5. 打包
回到项目根路径

pyinstaller -p venv/Scripts -F -w xxx.py