python-GUI:利用pyqt5设计一个bootloader上位机页面(ZLG驱动)及打包报错faild to execute script pyi_rth_multiprocessing精简方案
python-GUI:利用pyqt5设计一个bootloader上位机页面1.下载pyqt5和Qt Designer2.利用Qt Designer设计页面步骤一:打开Qt Designer步骤二:设计页面步骤三:保存UI文件步骤四:.UI文件转.py文件3.架构设计(界面和逻辑分离)核心思路以该bootloader项目为例分析UI界面b3.py逻辑ZLG驱动逻辑(因为这个例子要用到硬件驱动,不看可
python-GUI:利用pyqt5设计一个bootloader上位机页面
最近有空,打算整理一下pyqt5的开发流程
开发环境 | 说明 |
---|---|
操作系统 | window7 |
python环境 | python 3.8 |
开发平台 | pycharm |
PyQt5 | 5.15.4 |
1.下载pyqt5和Qt Designer
3个月前安装的,有点忘了,当时也是一言难尽,pip老是下载不成功,不知道是不是还要安装啥依赖包,参考这个网址看看吧
pip install Sip
pip install pyqt5
pip install pyqt5-tools PyQt5不再提供Qt Designer等工具,所以需要再安装pyqt5-tools
说明:
Qt Designer是pyqt5的图形化设计界面,设计好的页面保存为.ui文件 然后执行
pyuic5 -o main.py main.ui 即可将.ui文件转化成.py代码,当然你不想安装的话也可以直接
用pyqt5库里的语法写。
优点:
1,Qt Designer界面控件可以直接拖到自己想要的位置(所见即所得),并进行编辑;如果仅仅是写代码,
还要运行看一下,看看摆放位置是不是自己心仪的位置,这点比较麻烦。(不容杠精反驳)
2,Qt Designer设计完成运行pyuic5命令可以直接生成代码,提高开发效率。
2.利用Qt Designer设计页面
步骤一:打开Qt Designer
pycharm – Tools – External Tools – Qt Designer
步骤二:设计页面
拖动左侧的图标至页面,摆放到自己想要的位置,并进行UI界面编辑设计。
步骤三:保存UI文件
b3.ui
步骤四:.UI文件转.py文件
pyuic5 -o b3.py b3.ui
-- b3.py是要生成的py文件名 ,当然你也可以改成ex01.py啥的
-- b3.ui是我要使用的ui文件
3.架构设计(界面和逻辑分离)
核心思路
以该bootloader项目为例分析
UI界面
b3.py
就是刚才.ui文件生成的.py文件(无需改动)
逻辑
ZLG驱动逻辑(因为这个例子要用到硬件驱动,不看可以跳过)
简单的提一下ZLG的python驱动下载、库文件、Demo程序的要点和注意点。
周立功官网找CAN驱动的资料每次都会迷路,如果下面链接点不进去,参照后面图片的指示从官网首页慢慢点进去
下载好周立功驱动python版的库文件、接口文档、上位机例程之后,我只想要驱动,剩下的功能自己开发。
这里有个注意点:
zlgcan.dll文件
kerneldlls文件夹
zlgcan.py
dev_info.json
这4样要和你的main.py放在同级目录下,并且修改zlgcan.py中调dll文件的路径为当前路径,如下图所示。
这样才不容易出现库文件啥的调用失败,用的时候直接import zlgcan 调zlgcan.py里的函数就好了。
因为我嫌zlgcan.py函数里的原始函数用起来会使得代码可读性变差,我又写了一个zlg_driver.py对zlgcan.py
做了二次封装。
项目Bootloader
zlgcan.py
UDS协议逻辑(因为这个例子要用到CAN通信协议,不看可以跳过)
CAN通信模块虽然就只是代替手动发一些UDS协议的指令,但是代码逻辑量还是多的,算是整个项目中工作量最大的地方了,写吐了。(对CAN驱动的UDS不熟悉的可以自行去百度:UDS协议)
事件绑定逻辑
举个例子
b3.ui
b3.py
比如我这里有个单选按钮,在UI生成的b3.py代码里的控件名叫radioButton,我想点击触发一个事件该怎么做呢?
很简单:
1,控件绑定事件函数
#connect_device
self.radioButton.clicked.connect(self.connect_ZLG)
self.radioButton_2.clicked.connect(self.disconnect_ZLG)
将按钮绑定到事件函数self.disconnect_ZLG,然后在事件函数里写自己的逻辑。
2,事件函数逻辑
比如我这里写了一个关闭驱动并在文本页面打印字符串"Device close."的功能。
def disconnect_ZLG(self):
self.radioButton.setChecked(False)
self.z.close_device()
self.textBrowser.append("Device close.")
核心思路:
1, self.控件名.cliced.connect(self.事件函数名) 注意这里connect里写的参数是函数名,
而不是函数,因此不要带括号()
2,然后在事件函数中写自己想要实现的功能逻辑
4.pyqt项目打包成exe
步骤一:pip install pyinstaller
步骤二:pyinstaller -F -w main.py
如果main.py在项目里调用了别的py文件,打包的main.py必须是项目中路径下的main.py 否则会提示找不到模块
pyinstaller -F -w ex1.py ex1.py为要运行的主py文件
会在当前目录下生成3样东西:
build文件夹 类似于C语言编译的.o文件,中间过程文件
dist文件夹 exe程序主文件
ex1.spec 这个为ex1.exe的配置文件,可以配置一些依赖包啥的,然后运行pyinstaller ex1.spec
如果有依赖包的话,直接运行exe是会报错的,将依赖包导入后正常可运行。(依赖包说明看步骤三)
运行dist文件夹中的ex1.exe并进行测试,发现程序可以运行;
并且在没有python环境的电脑上可以直接使用(亲测核实可用)。
步骤三:加载依赖包
要用到依赖包的,把依赖包(文件、文件夹都可以)直接拖入dist文件夹中,放的位置和你项目里的主py文件
对应的位置关系一样。
简而言之,把dist类比成你的项目,依赖包该放什么位置对应放进去就好了。
可以类比对照着下面两个图理解。
看明白了,觉得很简单了吧? 网上一堆人写的用pyinstaller啥啥啥命令,又或者是让你去改.spec配置文件
,但是又说不清楚的垃圾文章,看的我头都晕了,真的是又麻烦又垃圾。
项目名bootloader
dist文件夹
步骤四:exe程序测试(非python环境可用——亲测可用)
当初用pyinstaller ex1.py 和 pyinstaller -F -w ex1.py发现前者生成的dist文件中有很多pyqt5.dll
啥的包,而后者很简洁啥都没有,我在怀疑后者在无Python环境的电脑中是否可用?
照着pyinstaller -F -w main.py编译出的3个东西(build文件夹、dist文件夹、ex1.spec),
然后依赖包配好,整理成一个文件夹,并且在当前电脑可运行后;我将整理成的文件夹拷到别的没有python环境的
电脑上运行,发现可以直接用。
(不用质疑为什么里面没有pyqt5.dll或者啥啥py文件,这些估计都变成了build文件夹里的中间文件了)
5.其他(bootloader项目用到的一些技术)
SREC文件解析
简略提一提解析构造
示例: S31500A6A0AA0070002011A4000079A4000079A40000CB
说明 | |
---|---|
S3 | Type |
15 | 指0x15,count(地址+数据+校验和),一个16位count增1,也就是每数2位count增1 |
00A6A0AA | 32位地址 |
data | 数据 |
CB | checksum |
进度条实现思路
例:self.progressBar.setProperty("value", 24)
24表示设置进度条的值为24%(数字和绿色进度条是根据value设置的值对应变化的)
也就是说,我们可以在循环中,按百分比去set进度条的值。
例如: self.progressBar.setProperty("value", ((i+1)/total)*100)
6.总结
1,界面和架构分离的设计思路(主Py)
2,UI界面可以独立成一个Py文件供主py导入
如果需要预览纯UI界面的py文件,直接运行是打不开的;
需要在if__main__()函数这样写:
app = QApplication(sys.argv) # 创建应用程序
mainwindow = QMainWindow() # 创建主窗口
ui = Ui_MainWindow() # 调用Ui_MainWindow类主窗口
ui.setupUi(mainwindow) # 向主窗口添加控件
mainwindow.show() # 显示窗口
sys.exit(app.exec_()) # 程序执行循环
3,打包exe
7.打包后遇到的问题
用命令pyinstaller -F -w main.py (main.py必须是项目中路径下的main.py 否则会提示找不到模块)
打包后的exe(不能单独拿出来,只能build文件夹和dist文件夹放一起)
可以在无python环境的电脑下运行
pyinstaller 打包的exe在某些win7上面报错 faild to execute script pyi_rth_multiprocessing
参考这篇:pyinstaller 打包的exe在某些win7上面报错 faild to execute script pyi_rth_multiprocessing
本人已经核实:
1,用python3.6以上版本的环境打包的exe在有些win7电脑没有KB2533623补丁,需要把这个windows补丁打上,
按提示重启即可打开exe。
2.用python3.6环境再打包一下项目,编译出来的exe可以在没有KB2533623补丁的win7打开。
也就是说:
打包环境 | 说明 |
---|---|
python3.6以上 | 未安装python环境的电脑可用;部分未打KB2533623补丁的Win7电脑会打不开报错 |
python3.6 | 未安装python环境的电脑可用;任何win7、win10等都能用(不用打补丁) |
作为一个打工仔,你总不可能要求客户去打补丁吧?
但是我的电脑上的python环境又是python3.8,我得下一个python3.6环境,但是pip又会默认是3.8的,
(平时都不用python3.6)我又懒得配置。
于是乎,我想到了一个法子。
1,下载python3.6环境
2,打开pycharm,新建一个虚拟环境的工程,环境选择你下载的python3.6路径
3,将要打包的文件复制粘贴到这个新的虚拟环境工程下
4,在pycharm控制台pip下载pyinstaller以及一些你报红的import的包
(我这里目前就只有一个pyqt5要下载,虚拟环境的下载速度感觉比本地快得多)
5,在控制台pyinstaller -F -w main.py (main.py为要打包的exe)
6,如果有依赖包dll啥的放好,build和dist放一起,exe要在dist下打开,不多赘述了。
经过以上操作,打包后的exe可以在任何windows电脑上打开,包括无python环境的电脑。
更多推荐
所有评论(0)