Python-GUI wxPython之自动化数据生成器的项目实战
作者:BetterFate! 发布时间:2021-06-08 14:43:18
学习目标
根据原型设计编译自动化数据生成器,熟悉wxPython的基本用法。
界面原型设计
界面原型设计分析
输入参数:
最大长度
最小长度
组成规则
多少组数据
是否生成文件
文件名及路径设置
处理方式:
确定
重置
输出结果:
显示运行结果
相关提示信息
控件选择:
文本框复选框按钮消息对话框
文本框
复选框
按钮
消息对话框
分析设计过程及涉及技术 使用面向对象的思想实现:
创建类
初始化方法---定义创建所需要用到的GUI控件(app、window、panel、所需其他控件)
控件布局方法---控件布局设置
平行---一般来说逐行进行布局排列
垂直---最后统一进行垂直布局排列
事件关联方法---把对应的按钮所触发的事件进行绑定
事件处理方法---绑定之后要执行的处理代码
运行方法---窗体加载和App的运行
使用技术:
控件:
标签:wx.StaticText(self.panel, label="最小长度")
文本框:wx.TextCtrl(self.panel)
复选框:wx.CheckBox(self.panel, label="包含大写字母")
按钮:wx.Button(self.panel, label="确定")
多行文本框:wx.TextCtrl(self.panelnew, value=resultdata, style=wx.TE_MULTILINE, size=(400, 300))
错误提示框:
定义提示框内容,标题,默认确认按钮,窗口类型
当点击确定按钮之后,窗口关闭。dlg = wx.MessageDialog(None, "最小长度不能为空!", "错误信息", wx.YES_DEFAULT | wx.ICON_QUESTION)
if dlg.ShowModal() == wx.ID_YES:
dlg.Destroy()运行结果如下:
random:
在一个范围内随机取值:random.randint(x, y)
在给定的字符串中随机取一段任意长度的字符串:random.sample(给定字符串, 长度)
string:
大小写字母都有:string.ascii_letters
大写字母:string.ascii_uppercase
小写字母:string.ascii_lowercase
数字:string.digits
符号:string.punctuation
代码实现
# 使用面向对象编程实现基于GUI框架的自动生成测试数据的工具
# 导入库文件
import wx
import string, random
import csv
# 类的定义
class GUI_CreateTestData():
# 类的初始化定义,创建所有使用到的控件
def __init__(self):
# 初始化App
self.app = wx.App()
# 定义窗体
self.window = wx.Frame(None, title="自动创建测试数据工具", size=(400, 300))
# 定义Panel
self.panel = wx.Panel(self.window)
# 定义标签
self.lblminlen = wx.StaticText(self.panel, label="最小长度")
# 定义文本框
self.txtminlen = wx.TextCtrl(self.panel)
# 定义标签
self.lblmaxlen = wx.StaticText(self.panel, label="最大长度")
# 定义文本框
self.txtmaxlen = wx.TextCtrl(self.panel)
# 定义复选框
self.chkup = wx.CheckBox(self.panel, label="包含大写字母")
self.chklow = wx.CheckBox(self.panel, label="包含小写字母")
self.chknum = wx.CheckBox(self.panel, label="包含数字")
self.chkpnu = wx.CheckBox(self.panel, label="包含符号")
self.chkno = wx.CheckBox(self.panel, label="包含序号")
self.chkrexemail = wx.CheckBox(self.panel, label="包含邮箱后缀")
self.chkfile = wx.CheckBox(self.panel, label="保存到文件")
# 定义标签
self.lblfile = wx.StaticText(self.panel, label="文件名及路径选择")
# 定义文本框
self.txtfile = wx.TextCtrl(self.panel)
# 定义标签
self.lblcount = wx.StaticText(self.panel, label="数据总数")
# 定义文本框
self.txtcount = wx.TextCtrl(self.panel, value='1') # 默认值为1
# 定义两个按钮
self.butok = wx.Button(self.panel, label="确定")
self.butreset = wx.Button(self.panel, label="重置")
# 设置控件布局
def layout(self):
# 设置第一行的水平布局
boxsizer1 = wx.BoxSizer(wx.HORIZONTAL)
boxsizer1.Add(self.lblminlen, border=10, flag=wx.LEFT)
boxsizer1.Add(self.txtminlen, border=10, flag=wx.LEFT)
boxsizer1.Add(self.lblmaxlen, border=10, flag=wx.LEFT)
boxsizer1.Add(self.txtmaxlen, border=10, flag=wx.LEFT)
# 设置第二行的水平布局
boxsizer2 = wx.BoxSizer(wx.HORIZONTAL)
boxsizer2.Add(self.chkup, border=68, flag=wx.LEFT)
boxsizer2.Add(self.chklow, border=85, flag=wx.LEFT)
# 设置第三行的水平布局
boxsizer3 = wx.BoxSizer(wx.HORIZONTAL)
boxsizer3.Add(self.chknum, border=68, flag=wx.LEFT)
boxsizer3.Add(self.chkpnu, border=109, flag=wx.LEFT)
# 设置第四行的水平布局
boxsizer4 = wx.BoxSizer(wx.HORIZONTAL)
boxsizer4.Add(self.chkno, border=68, flag=wx.LEFT)
boxsizer4.Add(self.chkrexemail, border=110, flag=wx.LEFT)
# 设置第五行的水平布局
boxsizer5 = wx.BoxSizer(wx.HORIZONTAL)
boxsizer5.Add(self.chkfile, border=68, flag=wx.LEFT)
boxsizer5.Add(self.lblfile, border=10, flag=wx.LEFT)
boxsizer5.Add(self.txtfile, border=10, flag=wx.LEFT | wx.RIGHT)
# 设置第六行的水平布局
boxsizer6 = wx.BoxSizer(wx.HORIZONTAL)
boxsizer6.Add(self.lblcount, border=10, flag=wx.LEFT)
boxsizer6.Add(self.txtcount, border=10, flag=wx.LEFT | wx.RIGHT, proportion=1)
# 设置第七行的水平布局
boxsizer7 = wx.BoxSizer(wx.HORIZONTAL)
boxsizer7.Add(self.butok, border=68, flag=wx.LEFT)
boxsizer7.Add(self.butreset, border=109, flag=wx.LEFT)
# 设置垂直布局
boxsizerFinal = wx.BoxSizer(wx.VERTICAL)
boxsizerFinal.Add(boxsizer1, border=20, flag=wx.TOP)
boxsizerFinal.Add(boxsizer2, border=15, flag=wx.TOP)
boxsizerFinal.Add(boxsizer3, border=10, flag=wx.TOP)
boxsizerFinal.Add(boxsizer4, border=10, flag=wx.TOP)
boxsizerFinal.Add(boxsizer5, border=10, flag=wx.TOP)
boxsizerFinal.Add(boxsizer6, border=10, flag=wx.EXPAND | wx.TOP)
boxsizerFinal.Add(boxsizer7, border=10, flag=wx.TOP)
# for i in range(1, 8):
# box = "boxsizer" + str(i)
# # print(type(box))
# # print(type(eval(box)))
# boxsizerFinal.Add(eval(box)) # eval方法将字符串类型转换为对象
# 执行布局设置
self.panel.SetSizer(boxsizerFinal)
# 运行GUI整体框架
def eventbind(self):
# 绑定确定按钮对应的事件
self.butok.Bind(wx.EVT_BUTTON, self.checkinput)
self.butreset.Bind(wx.EVT_BUTTON, self.reset)
def checkinput(self, event):
# 对长度进行校验
# self.checklen()
lentmp = self.checklen()
if lentmp == 0:
# 没有选择任何条件,默认生成字母串
chkresult = self.nonemethod()
# print('是否勾选复选框', chkresult)
number = self.checknum()
strtmp = ""
# 返回值为0,任何条件都没有选择
if chkresult == 0 and number != 0:
for i in range(1, number + 1):
resultdata = self.createdata()
strtmp = strtmp + resultdata + '\n'
print(strtmp)
# 调用测试数据的显示
if self.chkfile.GetValue() == False:
# 调用一个新窗体,进行测试数据的显示
self.showdata(strtmp)
else:
# 调用保存文件方法
self.savefile(strtmp)
elif chkresult != 0 and number != 0:
for i in range(1, number + 1):
resultdata = self.createdatamethod(i)
strtmp = strtmp + resultdata + '\n'
print(strtmp)
# 调用测试数据的显示
if self.chkfile.GetValue() == False:
# 调用一个新窗体,进行测试数据的显示
self.showdata(strtmp)
else:
# 调用保存文件方法
self.savefile(strtmp)
# 保存文件处理
def savefile(self, resultdata):
# 首先判断文件名文本框是否输入合法的路径及文件名内容
filetmp = self.txtfile.GetValue()
# 判断是否为空
if filetmp == "":
dlg = wx.MessageDialog(None, "请输入文件名及路径", "错误信息", wx.YES_DEFAULT | wx.ICON_QUESTION)
if dlg.ShowModal() == wx.ID_YES:
dlg.Destroy()
return 0
else:
# 路径及文件名正确
# 创建一个文件
file = open(filetmp, 'w', newline='')
write = csv.writer(file)
tmp = resultdata.split("\n")
for ele in tmp:
write.writerow([ele])
file.close()
# 在新窗口中显示数据
def showdata(self, resultdata):
self.windownew = wx.Frame(None, title="显示测试数据", size=(400, 300))
# 窗口中创建一个panel
self.panelnew = wx.Panel(self.windownew)
# 再定义一个多行文本框
wx.TextCtrl(self.panelnew, value=resultdata, style=wx.TE_MULTILINE, size=(400, 300))
self.windownew.Show(True)
# 校验输入的数量
def checknum(self):
# 判断数量文本框是否为空
number = int(self.txtcount.GetValue())
if number == "" or number < 1:
# 弹出错误提示框
dlg = wx.MessageDialog(None, "请输入数量为大于等于1的整数!", "错误信息", wx.YES_DEFAULT | wx.ICON_QUESTION)
if dlg.ShowModal() == wx.ID_YES:
dlg.Destroy()
return 0
else:
return number
# 根据选择的组成条件生成数据
def createdatamethod(self, number):
strtmp = ""
self.no = number
rexemail = ['@51testing', '@126.com', '@163.com', '@qq.com', '@sohu.com']
# 判断生成的是哪些条件
if 'up' in self.chkList:
strtmp = strtmp + string.ascii_uppercase + string.ascii_uppercase + string.ascii_uppercase + string.ascii_uppercase
if 'low' in self.chkList:
strtmp = strtmp + string.ascii_lowercase + string.ascii_lowercase + string.ascii_lowercase + string.ascii_lowercase
if 'num' in self.chkList:
strtmp = strtmp + string.digits + string.digits + string.digits + string.digits + string.digits + string.digits + string.digits + string.digits
if 'pnu' in self.chkList:
strtmp = strtmp + string.punctuation + string.punctuation + string.punctuation + string.punctuation + string.punctuation + string.punctuation
num = random.randint(int(self.minlen), int(self.maxlen))
# 获取子串,前面的条件至少选择一个
if strtmp != "":
resultdata = ''.join(random.sample(strtmp, num))
else:
# 如果其他条件都没有选择,默认调用生成字母串
resultdata = self.createdata()
# 添加一个序号
if 'no' in self.chkList:
resultdata = str(self.no) + "、" + resultdata
if 'email' in self.chkList:
# 任意取出一个邮箱后缀
eml = random.choice(rexemail)
resultdata = resultdata + eml
# print(resultdata)
return resultdata
# 对界面输入进行校验
def checklen(self):
minlen = self.txtminlen.GetValue()
maxlen = self.txtmaxlen.GetValue()
self.minlen = minlen.strip() # 去除左右空格方法
self.maxlen = maxlen.strip()
# 判断最小长度文本框中输入的内容是否为空
if self.minlen == "":
# 给出提示,最小长度不能为空
dlg = wx.MessageDialog(None, "最小长度不能为空!", "错误信息", wx.YES_DEFAULT | wx.ICON_QUESTION)
if dlg.ShowModal() == wx.ID_YES:
dlg.Destroy()
# 判断最大长度文本框中输入的内容是否为空
elif self.maxlen == "":
# 给出提示,最小长度不能为空
dlg = wx.MessageDialog(None, "最大长度不能为空!", "错误信息", wx.YES_DEFAULT | wx.ICON_QUESTION)
if dlg.ShowModal() == wx.ID_YES:
dlg.Destroy()
# 判断最小长度是否小于最大长度
elif int(self.minlen) > int(self.maxlen):
# 给出提示,最小长度不能大于最大长度
dlg = wx.MessageDialog(None, "最小长度不能大于最大长度!", "错误信息", wx.YES_DEFAULT | wx.ICON_QUESTION)
if dlg.ShowModal() == wx.ID_YES:
dlg.Destroy()
else:
return 0
return 1
# 没有选中任何check框生成字母串
def nonemethod(self):
# 把check框的选项放入列表中
self.chkList = []
# 判断check框是否没有任何选择
if self.chkup.GetValue() == True:
self.chkList.append('up')
if self.chklow.GetValue() == True:
self.chkList.append('low')
if self.chknum.GetValue() == True:
self.chkList.append('num')
if self.chkpnu.GetValue() == True:
self.chkList.append('pnu')
if self.chkno.GetValue() == True:
self.chkList.append('no')
if self.chkrexemail.GetValue() == True:
self.chkList.append('email')
# print(self.chkList)
# 判断list列表是否为空
if len(self.chkList) == 0:
return 0
else:
return 1
# 把界面所有输入内容清空
def reset(self, event):
dlg = wx.MessageDialog(None, "是否确定要清空信息?", "清空确认信息", wx.YES_NO | wx.ICON_QUESTION)
if dlg.ShowModal() == wx.ID_YES:
dlg.Destroy()
self.txtminlen.SetValue("")
self.txtmaxlen.SetValue("")
self.chkup.SetValue(False)
self.chklow.SetValue(False)
self.chknum.SetValue(False)
self.chkpnu.SetValue(False)
self.chkno.SetValue(False)
self.chkrexemail.SetValue(False)
self.txtcount.SetValue("1")
else:
dlg.Destroy()
# 创建测试数据
def createdata(self):
str = ""
# 按照指定长度生成测试数据
# 生成随机数
num = random.randint(int(self.minlen), int(self.maxlen))
# 默认生成字母串
str = str + string.ascii_letters + string.ascii_letters + string.ascii_letters + string.ascii_letters
# 获取子串
resultdata = ''.join(random.sample(str, num))
# print(resultdata)
return resultdata
def run(self):
# 激活显示窗口
self.window.Show(True)
# 运行程序
self.app.MainLoop()
if __name__ == '__main__':
guiObj = GUI_CreateTestData()
guiObj.layout()
guiObj.eventbind()
guiObj.run()
运行结果如下:
来源:https://blog.csdn.net/weixin_42297382/article/details/124769965
猜你喜欢
- 效果图如下所示: 前言嗨,说起探探想必各位程序汪都不陌生(毕竟妹子很多),能在上面丝滑的翻牌子,探探的的堆叠滑动组件起到了关键的作
- 序言本文所提及的VTD-XML并非本文作者原创,作者只是对它进行介绍。问题通常当我们提起XML的使用时,最头痛的部分便是XML的verbos
- 1、JavaScript方法:document.getElementById("id").innerHTML; (1)实
- 问题:有一个列表,每一个条目都是这篇文章的部分内容,类似这样:<div class="list">
- 今天的主题!最近很多朋友问起pyecharts,尤其是地理坐标图的制作,都说被其图形之美给吸引到了。刚好今天也有同事问起来,那么今天就以py
- 视图(View)“视图”主要指我们送到Web浏览器的最终结果??比如我们的脚本生成的HTML。当说到视图时,很多人想到的是模版,但是把模板方
- 说到网络产品,离不开的话题就是用户,就像传统行业的消费者。人是复杂的,网民的用户行为更加复杂,用户和用户是不一样的,或者说,每个用户都不一样
- 一、xlrd的安装打开cmd输入pip install xlrd安装完成即可二、xlrd模块的使用下面以这个工作簿为例1、导入模块impor
- 油画的实现原理油画简单的理解是带有艺术感的图像,色彩相对于原图要更加鲜艳,但却是失真的。而且对于喜欢欣赏艺术的读者,肯定或多或少关注过油画,
- LoadRunner监控MySQLhttp://www.docin.com/p-92272846.htmlAdvanced MySQL Pe
- OUTLINE 常见的时间字符串与timestamp之间的转换日期与timestamp之间的转换常见的时间字符串与timesta
- 说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家!一丶说明测试条件:需要有GitHub账号以及在本地安装了Git工具,无论
- 本文实例讲述了Python自定义函数计算给定日期是该年第几天的方法。分享给大家供大家参考,具体如下:写一个函数,计算给定日期是该年的第几天.
- 这段时间因为要做个网站,而空间又不支持ASP,所以又拿起JavaScript教程看了下,看能不能在静态的空间里实现动态,当然,这个动态不是真
- 一、基本思想本文思想是基于用asp和DOM来读取和存储XML数据,并利用XML数据来存储留言信息,达到同用数据库存储数据的功能。二、XML留
- 目录实验环境准备API 寻找 && 提取代码实现项目链接我身边的很多小伙伴们在朋友圈里面晒着出去游玩的照片,简直了,人多的不
- 一、决策树的特点1.优点具有很好的解释性,模型可以生成可以理解的规则。可以发现特征的重要程度。模型的计算复杂度较低。2.缺点模型容易过拟合,
- 前言SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库,这意味着与其
- 导言就计算机科学而言,caching就是将所需要的数据或信息的备份放在某个地方,便于快速访问的这样一个过程。以数据处理(data-drive
- 今天一个项目上需要,修改了一些属性,测试成功。<!--#include file="conn.asp"-