前言

因为压测一个系统,需要大量的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,安装到本地。默认安装。

Python开发软件案例 用python开发软件_Python开发软件案例

二、wxFormBuild创建工具图形可视化界面

1、先选择项目保存代码为python,代码文件名称window。

Python开发软件案例 用python开发软件_txt文件_02

2、选择Frame控件、Layout方式等,这里参考学习:
https://zhuanlan.zhihu.com/p/107451739?utm_source=wechat_session 建立以下界面,可以输入年份,选择地区,然后生成,下方可以选择文件夹保存生成的txt文件。
点击‘开始生成’按钮后,程序开始运行,建立txt文件,进度条实时更新。Python开发软件案例 用python开发软件_Python开发软件案例_03
3、建立报错与成功提示弹窗Dialog,在选择错误地址与生成完成时,弹窗提示。
Python开发软件案例 用python开发软件_Python开发软件案例_04
添加事件绑定,按钮与进度条方法
4、F8保存代码,或者复制python页面的代码使用。
Python开发软件案例 用python开发软件_Python开发软件案例_05

三、界面方法调试

1、将上面生成的window.py文件放到项目下面,主文件内导入GUI界面

import window。因为上面自动生成的window.py内容会随着界面变化而变化,所以不要直接修改这个文件。

Python开发软件案例 用python开发软件_Python开发软件案例_06


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文件,本来以为可以完工了,但工具界面立马提示未响应,程序假死。。。

Python开发软件案例 用python开发软件_python_07

四、线程解决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里面。但是又发现一个问题,生成的文件偏大,这不能忍。百度去。

Python开发软件案例 用python开发软件_python_08


2、网上说主要原因是pyinstaller会把python环境中的很多项目没有用到的包都一起打包进去,这样就增大了exe的大小。

解决方法是使用虚拟环境,如:pipenv库、anaconda创建的虚拟环境

参考:


https://zhuanlan.zhihu.com/p/348120084 3、两个环境都试了,都可以用,打包的程序差不多大小。最后工具9M多点点。

总结

制作小工具之路,一步一坑,但也学到了wxPython、pub等基础使用,以后再有类似开发相信会更得心应手。
人生苦短,我学python。
工具与代码放盘里了,链接:https://pan.baidu.com/s/18sJiBU6cmVOeitVNgjyT1Q
提取码:b2ie