前言
因为压测一个系统,需要大量的id。网上找的工具一次最多生成500个,完全是杯水车薪了。就找了python生成的代码,修改成一次生成36万个,这次够用了。为了方便以后使用,就学习开发一个GUI界面,将之打包成exe小工具。这里记录一下整个学习流程。
选择使用wxPython配套的开发工具wxFormBuilder,它的图形可视化界面可以快速直观的帮助我搭建起GUI界面。
一、wxPython环境准备
1、wxPython可以从官方网站http://wxpython.org下载,或者使用pip下载wxPython依赖库。
pip installer wxPython
2、安装图形可视化生成工具
wxFormBuilder 是一款开源的跨平台WYSIWYG GUI构建器,可将wxWidget GUI设计转换为C ++,Python,PHP或XML格式。
github项目地址https://github.com/wxFormBuilder/wxFormBuilder,
这里下载最新版https://github.com/wxFormBuilder/wxFormBuilder/releases,安装到本地。默认安装。
二、wxFormBuild创建工具图形可视化界面
1、先选择项目保存代码为python,代码文件名称window。
2、选择Frame控件、Layout方式等,这里参考学习:
https://zhuanlan.zhihu.com/p/107451739?utm_source=wechat_session 建立以下界面,可以输入年份,选择地区,然后生成,下方可以选择文件夹保存生成的txt文件。
点击‘开始生成’按钮后,程序开始运行,建立txt文件,进度条实时更新。
3、建立报错与成功提示弹窗Dialog,在选择错误地址与生成完成时,弹窗提示。
添加事件绑定,按钮与进度条方法
4、F8保存代码,或者复制python页面的代码使用。
三、界面方法调试
1、将上面生成的window.py文件放到项目下面,主文件内导入GUI界面
import window。因为上面自动生成的window.py内容会随着界面变化而变化,所以不要直接修改这个文件。
2、初始化窗口,完善进度条与生成按钮的方法。
将生成id代码,放在按钮函数下面。(太长就不粘了)
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import wx #wxPython
import window
class ff1(window.MyDialog1):
'''失败提示弹窗'''
def __init__(self, parent):
window.MyDialog1.__init__(self, parent)
class ff2(window.MyDialog11):
'''成功提示弹窗'''
def __init__(self, parent):
window.MyDialog11.__init__(self, parent)
class MainWindow(window.sfz):
'''主窗口程序'''
def __init__(self, parent):
window.sfz.__init__(self,parent)
self.jindutiao=0 #进度条值
def m_gauge1OnChar(self, event):
'''进度条'''
self.m_gauge1.SetValue(self.jindutiao) #更新进度条
if self.jindutiao == 100 :
self.m_button1.Enable() #启用按钮
dialog=ff2(main_win) #成功弹窗
dialog.ShowModal()
def gennerator(self, event):
'''
生成按钮:获取年份、地区、保存地址等
'''
self.jindutiao=0 #按下按钮,置为0。不报错后续置灰按钮
year= str(self.year1.GetValue()) #年份 GetValue()返回当前文本框中的所有文案
where=self.where1.GetStringSelection() #地区 GetStringSelection() 返回当前文本框中选中的文本
for key, value in bianma.AREA_INFO.items():
if value == where:
AREA2 = key #地区编码
path=self.path.GetPath() #保存路径判断
if path == "不选地址,文件默认保存在桌面":
path = os.path.join(os.path.expanduser("~"), 'Desktop') #获取桌面路径
elif os.path.exists(path) == True: #判断路径是否存在
path = self.path.GetPath()
else:
dialog=ff1(main_win) #错误提示框
dialog.ShowModal()
self.jindutiao=-1
if self.jindutiao>=0:
event.GetEventObject().Disable() #禁用按钮
3、启动GUI界面
if __name__ == '__main__':
app = wx.App() #每一个wxPython应用程序都是一个wx.App实例
main_win = MainWindow(None) #None表示这个frame是顶层的框架,没有父框架
main_win.Show(True) #show()方法激活窗体,True显示这个Frame(窗口);False,隐藏窗口;
app.MainLoop() #运行程序
4、运行程序,点击生成按钮,程序在桌面成功建立了txt文件,本来以为可以完工了,但工具界面立马提示未响应,程序假死。。。
四、线程解决wxpython界面无响应假死问题
1、出问题了,百度说计算时间太长,ui界面反应不了,程序就无响应。这当然要解决,思路是调用线程计算耗时的代码,pubsub在线程与界面之间通讯。
参考:
https://www.bajins.com/Python/PythonGUI.html#多线程防假死动态刷新界面
2、主程序新增pub.subscribe(self.m_gauge1OnChar, “update”),订阅
class MainWindow(window.sfz):
'''主窗口程序'''
def __init__(self, parent):
window.sfz.__init__(self,parent)
pub.subscribe(self.m_gauge1OnChar, "update")#发布一个叫update的主题,触发m_gauge1OnChar函数
def m_gauge1OnChar(self, event):
'''进度条'''
self.jindutiao = event
self.m_gauge1.SetValue(self.jindutiao) #更新进度条
3、生成程序放线程里面,用pub向GUI发消息。
经调试,假死问题解决。
class TestThread(threading.Thread):
'''多线程防假死与线程间传递消息'''
def __init__(self,year,where,path,AREA2):
self.year=year
self.where=where
self.path=path
self.AREA2=AREA2
threading.Thread.__init__(self) #线程实例化时立即启动
self.start()
self.jindutiao=0
def run(self):
"""线程执行合成身份证代码"""
'''计算耗时的代码略'''
pub.sendMessage("update", event=self.jindutiao) #发update消息,指定event参数的值
五、pyinstaller打包
1、首先安装pyinstaller 包
pip install pyinstaller
在代码文件夹内,打开cmd,使用命令打包成一个exe.
pyinstaller -F -w -i logo.ico sfz.py
生成exe文件在dist里面。但是又发现一个问题,生成的文件偏大,这不能忍。百度去。
2、网上说主要原因是pyinstaller会把python环境中的很多项目没有用到的包都一起打包进去,这样就增大了exe的大小。
解决方法是使用虚拟环境,如:pipenv库、anaconda创建的虚拟环境
参考:
https://zhuanlan.zhihu.com/p/348120084 3、两个环境都试了,都可以用,打包的程序差不多大小。最后工具9M多点点。
总结
制作小工具之路,一步一坑,但也学到了wxPython、pub等基础使用,以后再有类似开发相信会更得心应手。
人生苦短,我学python。
工具与代码放盘里了,链接:https://pan.baidu.com/s/18sJiBU6cmVOeitVNgjyT1Q
提取码:b2ie