欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程语言 > python >内容正文

python

wxFormBuilder + wxPython手撸丑陋计算器

发布时间:2023/12/20 python 41 豆豆
生活随笔 收集整理的这篇文章主要介绍了 wxFormBuilder + wxPython手撸丑陋计算器 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

目录

前言

一、设计计算器图形界面

1、建Project

2、设计主体框的属性

3、设计计算器页面布局

二、代码架构设计

1、将计算器运行起来

 2、添加按钮事件

3、代码实现

4、运行计算器

三、测试计算器逻辑


前言

wxPtyhon它是Python语言的跨平台GUI工具包。使用wxPython软件开发人员可以为他们的Python应用程序创建真正的本地用户界面。

wxFormBuilder是一个图片界面生成器,其生成的界面可以翻译成为C++、python、PHP、Lua、XRC代码。本文开源,跨平台,自动生成生成代码,提高开发效率的特性,用不用它,仁者见仁,智者见智。用熟悉了,什么工具都可达到最终目的,也可以不用工具,直接使用GUI库手撸客户端工具,大神一般是这么做的。所以本文适合刚上手wxPython,但又急于想开发客户端工具的人看。

本文会仔细描述wxFormBuilder如何拖拽出一个丑陋的计算器,生成wxPython代码;然后在这个基础上再描述实现计算器的计算功能的过程

代码编器使用PyCharm,阅读本文需要有Python基础,略微了解wxPython。

丑陋的计算器呈现效果如下(后期可能更丑~~~~)

一、设计计算器图形界面

1、建Project

        打开wxFormBuilder,

        在Object Tree树下选择MyProject1:Project、

        点击Component Palotte 下Forms 的Tab页,点击Frame按钮(第一个),

        按下图数字标识,生成一个Frame框。这将会是计算器的主体。

        

2、设计主体框的属性

        属性Object Properties------ProperTies

        去掉标题栏

        Frame-----style  下的wxDEFAULT_FRAME_STYLE 取消勾选,

        标题栏去掉,最大化、最小化、关闭按钮跟着一并去掉了

   

        设置size

        最小为宽400px;长500px

        wxWindow-----minimum_size设置400;500,

       

        size 宽为400px:可横向摆上4例按钮 ,

        size 高为500px:可竖向摆上1个显示屏与5行按钮

3、设计计算器页面布局

        先将计算器画一下,明确布局,使用WxBoxSize布局

        

        上图标1是显示屏,占WxBoxSize一栏

        上图标2是按钮区,占WxBoxSize一栏

        上图标3是按钮分区,在2栏里嵌套一个WxBoxSize

        1)添加布局、显示

        在Object Tree选择MyFrame1:Frame,然后在Component Palatte里选择Layout布局Tab页,选择WxBoxSize添加       

        按图中数字顺序操作

        在bSizer1:wxBoxSize第一栏添加一个Text,

        Common 页中选择编辑框

        按图中数字顺序操作

        

        在BSizer1中添加一个wxBoxsize

        选择BSizer1:wxBoxSizer,进入Layout 页,添加一个WxBoxSizer,将这个WxBoxSizer的orient设置为WxHORIZONTAL (横向)

        按图中数字顺序操作

        

        在bSizer2中添加四个WxBoxSizer,

        操作方法与上面一样,只是添加一个,orient默认不动,此时主体框还看不出什么

        按图中数字顺序操作

        

        添加按钮,在BSizer3、BSizer4、BSizer5、BSizer6下,各添加5个按钮,

        调整所有按钮最小Size为70px; 60px

        按图中数字顺序操作

        

        设置显示屏属性与按钮字符修改

        显示屏样式

        Size设置:Minimum_size:370;80

        只读:wxREADONLY

        靠右:wxTE_RIGHT

        多行:wxTE_MULTILINE

        自行展示滚动条:wxTE_RICH  --------行数超过显示屏展示滚动条,未超过不展示

        显示屏中字体大小样式,因为这个wxFormBuilder可能没装好,无法设置,后期在代码里修改

        

        修改按钮展示字符,点击目标按钮,在Properties里找到label,改变其值,如下图

        按图中数字顺序操作

        注意:修改属性时,切换控件请勿直接点击另一个控件,大概率会导致wxFormBuilder崩溃。可以先点击上图3处空白地段,再点击另一个控件,这样就不会使wxFormBuilder崩溃。

        修改完按钮字符后,

        将第四列按钮删除一个,=号按钮高度调整为125px

        再将主体框高度调整为450px

        这里只给描述没给操作步骤,请自行按照前面的操作修改对应参数。

        计算器框效果图如下

        wxFormBuilder部分完成,接下来将将Editer由Designer切换到下图Python页,复制其中的py代码到下个章节开始做计算器后台逻辑的开发

生成的代码重新给了相关注释,输出如下: # -*- coding: utf-8 -*-########################################################################### ## Python code generated with wxFormBuilderormBuilder (version Jun 17 2015) ## http://www.wxFormBuilderormbuilder.org/ ## ## PLEASE DO "NOT" EDIT THIS FILE! ########################################################################### #导入wxPython相关的库 import wx      import wx.xrc########################################################################### ## Class MyFrame1 ###########################################################################class MyFrame1 ( wx.Frame ): #初始化构造框体, def __init__( self, parent ):#初始化父类,构造Frame框体,传入了父类对象,框体id,框体title,位置pos,大小size,风格style wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( -1,-1 ), style = 0|wx.TAB_TRAVERSAL )#设置框体大小,这里正式使用时要将self.SetSizeHintsSz改为self.SetSizeHints,国为self.SetSizeHintsSz是比较老版本wxPython中的方法了,新方法去掉了末尾Sz self.SetSizeHintsSz( wx.Size( 400,450 ), wx.DefaultSize )#创建第一个布局BoxSizer 为 bSizer1,纵向的 bSizer1 = wx.BoxSizer( wx.VERTICAL )#创建编辑框 self.m_textCtrl1 = wx.TextCtrl( self, wx.ID_ANY, u"1+2=\n3", wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE|wx.TE_READONLY|wx.TE_RICH|wx.TE_RIGHT )#设置编辑框的大小 self.m_textCtrl1.SetMinSize( wx.Size( 370,80 ) )#将编辑框加入到 bSizer1中去 bSizer1.Add( self.m_textCtrl1, 0, wx.ALL, 5 )#创建第二个布局BoxSizer 为 bSizer2,横向的 bSizer2 = wx.BoxSizer( wx.HORIZONTAL )#创建第三个布局BoxSizer 为 bSizer3,纵向的 bSizer3 = wx.BoxSizer( wx.VERTICAL )#创建第一个button按钮为m_button1 self.m_button1 = wx.Button( self, wx.ID_ANY, u"C", wx.DefaultPosition, wx.DefaultSize, 0 )#设置按钮的大小 self.m_button1.SetMinSize( wx.Size( 70,60 ) )#将m_button1加入后bSizer3中 bSizer3.Add( self.m_button1, 0, wx.ALL, 5 )self.m_button2 = wx.Button( self, wx.ID_ANY, u"7", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_button2.SetMinSize( wx.Size( 70,60 ) )bSizer3.Add( self.m_button2, 0, wx.ALL, 5 )self.m_button3 = wx.Button( self, wx.ID_ANY, u"4", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_button3.SetMinSize( wx.Size( 70,60 ) )bSizer3.Add( self.m_button3, 0, wx.ALL, 5 )self.m_button4 = wx.Button( self, wx.ID_ANY, u"1", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_button4.SetMinSize( wx.Size( 70,60 ) )bSizer3.Add( self.m_button4, 0, wx.ALL, 5 )self.m_button17 = wx.Button( self, wx.ID_ANY, u"%", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_button17.SetMinSize( wx.Size( 70,60 ) )bSizer3.Add( self.m_button17, 0, wx.ALL, 5 )#将纵向的bSizer3加入到横向的bSizer2中,实现例。后面还有三个纵向的bSizer要加入bSizer2中,实现四例的按钮组合 bSizer2.Add( bSizer3, 1, wx.EXPAND, 5 )#创建第四个布局BoxSizer 为 bSizer4,纵向的 bSizer4 = wx.BoxSizer( wx.VERTICAL )self.m_button5 = wx.Button( self, wx.ID_ANY, u"+", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_button5.SetMinSize( wx.Size( 70,60 ) )bSizer4.Add( self.m_button5, 0, wx.ALL, 5 )self.m_button6 = wx.Button( self, wx.ID_ANY, u"8", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_button6.SetMinSize( wx.Size( 70,60 ) )bSizer4.Add( self.m_button6, 0, wx.ALL, 5 )self.m_button7 = wx.Button( self, wx.ID_ANY, u"5", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_button7.SetMinSize( wx.Size( 70,60 ) )bSizer4.Add( self.m_button7, 0, wx.ALL, 5 )self.m_button8 = wx.Button( self, wx.ID_ANY, u"2", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_button8.SetMinSize( wx.Size( 70,60 ) )bSizer4.Add( self.m_button8, 0, wx.ALL, 5 )self.m_button18 = wx.Button( self, wx.ID_ANY, u"0", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_button18.SetMinSize( wx.Size( 70,60 ) )bSizer4.Add( self.m_button18, 0, wx.ALL, 5 )bSizer2.Add( bSizer4, 1, wx.EXPAND, 5 )#创建第五个布局BoxSizer 为 bSizer5,纵向的 bSizer5 = wx.BoxSizer( wx.VERTICAL )self.m_button9 = wx.Button( self, wx.ID_ANY, u"-", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_button9.SetMinSize( wx.Size( 70,60 ) )bSizer5.Add( self.m_button9, 0, wx.ALL, 5 )self.m_button10 = wx.Button( self, wx.ID_ANY, u"9", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_button10.SetMinSize( wx.Size( 70,60 ) )bSizer5.Add( self.m_button10, 0, wx.ALL, 5 )self.m_button11 = wx.Button( self, wx.ID_ANY, u"6", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_button11.SetMinSize( wx.Size( 70,60 ) )bSizer5.Add( self.m_button11, 0, wx.ALL, 5 )self.m_button12 = wx.Button( self, wx.ID_ANY, u"3", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_button12.SetMinSize( wx.Size( 70,60 ) )bSizer5.Add( self.m_button12, 0, wx.ALL, 5 )self.m_button19 = wx.Button( self, wx.ID_ANY, u".", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_button19.SetMinSize( wx.Size( 70,60 ) )bSizer5.Add( self.m_button19, 0, wx.ALL, 5 )bSizer2.Add( bSizer5, 1, wx.EXPAND, 5 )bSizer6 = wx.BoxSizer( wx.VERTICAL )self.m_button13 = wx.Button( self, wx.ID_ANY, u"<<", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_button13.SetMinSize( wx.Size( 70,60 ) )bSizer6.Add( self.m_button13, 0, wx.ALL, 5 )self.m_button14 = wx.Button( self, wx.ID_ANY, u"*", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_button14.SetMinSize( wx.Size( 70,60 ) )bSizer6.Add( self.m_button14, 0, wx.ALL, 5 )self.m_button15 = wx.Button( self, wx.ID_ANY, u"/", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_button15.SetMinSize( wx.Size( 70,60 ) )bSizer6.Add( self.m_button15, 0, wx.ALL, 5 )self.m_button16 = wx.Button( self, wx.ID_ANY, u"=", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_button16.SetMinSize( wx.Size( 70,125 ) )bSizer6.Add( self.m_button16, 0, wx.ALL, 5 )bSizer2.Add( bSizer6, 1, wx.EXPAND, 5 )#将横向的bSizer2加入bSizer1中第二个格子中,第一个格式是编辑框,第二个格子是按钮组全布局 bSizer1.Add( bSizer2, 1, wx.EXPAND, 5 )self.SetSizer( bSizer1 ) self.Layout() bSizer1.Fit( self )self.Centre( wx.BOTH )#析构函数   与 __init__相反,一个创造,一个毁灭 def __del__( self ): pass

二、代码架构设计

1、将计算器运行起来

      1)建工程目录

        随便新增一个目录,将此目录取为GUIDEMO目录

        使用pycharm ---file---Open   打开这个目录

        在目录下新增一个Python Package目录,命名为:Calculator

        

         

       2)复制图形界面Python代码

        在Calculator下新增一个python文件MainFarme.py

        将图形界面的python代码复制过来

        没有安装wxPython库的,代码中的import wx 会提示红色波浪线,

        使用命令安装:pip install wxpython

        注意,复制过来的代码中,有异常代码,会运行报错,整理一下

        找到self.SetSizeHintsSz改为:self.SetSizeHints

        

        在Calculator下新增一个python文件runMain.py

        在其中添加代码

import wx from MainFarme import MyFrame1''' 新建一个类,继承MyFrame1, ''' class newWindow(MyFrame1):pass''' 运行入口 添加wx对象 添加NewWindow对象 newWindow显示(show) '''if __name__=='__main__':app = wx.App()win = newWindow(None)win.Show()app.MainLoop()

        运行代码,出现了计算器窗口

        

此时,发现在。显示器中的字符未消失,且按钮响应事件未设置。

所以插入一拨wxFormBuilder的操作

一般我们写运行代码时,不直接使用MyFrame1创建对象,而是再用一个类继承MyFarme1。好处:就是在子类里修改代码不影响父类,如果我们调整图形界面,生成的新代码直接Copy过来用,无任何影响

 2、添加按钮事件

        回到wxFormBuilder点击按钮,在OjbectProperties下找到Events事件编辑,给OnButtonClick添加响应函数

        如C按钮,添加响应函数OnClear

        

        下面Bind方法就是绑定函数的方法

        自动生成OnClear函数,里面有事件跳过的代码。

        

         照模样将所有按钮都添加上事件如下。

       

         将最新代码Copy到MainFarme.py中来

        

3、代码实现

        之前我们做了newWindow继承MyFrame1的操作,是为了隔离图形界面修改,这算初步的封闭开发架构

        如果是真实开发一个中大型项目,肯定不只是一个框体,所以有可能有很多个MyFrame文件与类,如果是都放在同一个目录下面,那么管理起来会很麻烦。

        

        用目录分类管理代码文件,即使扩展再多的页面,也能条理清楚

        mainFarme.py是图形界面代码,这里便不展示了

        newWindow.py

#先继承MyFrame1,然后将所有按钮的点击事件覆盖,因为功能是要在这边实现 #定义了计算器算术式变量 self.formula_Text   计算结果self.result_Text #实现的功能中使用到了re正则表达式,导入正则表达式,导入 import re  #导入正则表达式 from MainFarme import MyFrame1   #导入计算器图形代码类 class NewWindow(MyFrame1):def __init__(self, parent):'''初始化:param parent:'''#计算器算术式self.formula_Text = ''#计算结果self.result_Text = ''super().__init__(parent)

按照逻辑与显示屏展示逻辑实现:

        1)显示器展示

  def set_Calculator_Text(self):'''设置显示器算式与计算结果:return:'''if self.result_Text != '':self.formula_Text += '\n' + self.result_Textself.m_textCtrl1.SetValue(self.formula_Text)

        2)清空按钮功能

    

def clear_Calculator_Text(self):'''清空显示屏:return:'''self.result_Text = ''self.formula_Text = ''self.m_textCtrl1.SetValue('')

        3)其他按钮实现  里面有使用到正则表达式,记录在最前面导入

   

  def btn_Response(self, btn_value):'''实现按钮的功能:param btn_value: 按钮符号:return:'''if self.result_Text != '' and btn_value != '<<':self.clear_Calculator_Text()# 运算符operation = ('+', '-', '*', '/', '%')# 如果已有内容是以小数点开头的,在前面加 0if self.formula_Text.startswith('.'):self.formula_Text = '0' + self.formula_Text  # 字符串可以直接用+来增加字符# 根据不同的按钮作出不同的反应if btn_value in '0123456789':# 按下 0-9 在 content 中追加self.formula_Text += btn_valueelif btn_value == '.':# 将 content 从 +-*/ 这些字符的地方分割开来lastPart = re.split(r'\+|-|\*|/|%', self.formula_Text)[-1]if '.' in lastPart:# 信息提示对话框returnelif len(lastPart) == 0:btn_value = '0' + btn_valueself.formula_Text += btn_valueelif btn_value == 'C':# 清除文本框self.formula_Text = ''elif btn_value == '<<':if self.result_Text != '':self.result_Text = ''self.formula_Text = self.formula_Text.split('\n')[0]self.formula_Text = self.formula_Text[:-1]elif btn_value == '=':try:# 对输入的表达式求值self.result_Text = str(eval(self.formula_Text))self.formula_Text += btn_valueexcept Exception as e:returnelif btn_value in operation:if self.formula_Text.endswith(operation):returnself.formula_Text += btn_valueself.set_Calculator_Text()

按钮逻辑实现完成后了,再实现按钮点击响应函数,子类实现覆盖父类响应函数

   

  def OnClear(self, event):'''清空:param event::return:'''self.btn_Response('C')def OnSeven(self, event):'''数字7:param event::return:'''self.btn_Response('7')def OnFour(self, event):'''数字4:param event::return:'''self.btn_Response('4')def OnOne(self, event):'''数字1:param event::return:'''self.btn_Response('1')def OnMorethan(self, event):'''按钮%:param event::return:'''self.btn_Response('%')def OnAdd(self, event):'''按钮+:param event::return:'''self.btn_Response('+')def Oneight(self, event):'''数字8:param event::return:'''self.btn_Response('8')def OnFive(self, event):'''数字5:param event::return:'''self.btn_Response('5')def OnTwo(self, event):'''数字2:param event::return:'''self.btn_Response('2')def OnZero(self, event):'''数字0:param event::return:'''self.btn_Response('0')def OnReduce(self, event):'''按钮-:param event::return:'''self.btn_Response('-')def OnNine(self, event):'''数字9:param event::return:'''self.btn_Response('9')def Onsix(self, event):'''数字6:param event::return:'''self.btn_Response('6')def Onthree(self, event):'''数字3:param event::return:'''self.btn_Response('3')def OnDecimal(self, event):'''小数点。:param event::return:'''self.btn_Response('.')def OnDel(self, event):'''退格 <<:param event::return:'''self.btn_Response('<<')def OnRide(self, event):'''按钮*:param event::return:'''self.btn_Response('*')def OnExcept(self, event):'''按钮/:param event::return:'''self.btn_Response('/')def OnEqualto(self, event):'''按钮=:param event::return:'''self.btn_Response('=')

4、运行计算器

在runMain.py文件里编写运行代码i

import wx from Calculator.manage.newWindow import NewWindow''' 运行入口 添加wx对象 添加NewWindow对象 newWindow显示(show) '''if __name__=='__main__':app = wx.App()win = NewWindow(None)win.Show()app.MainLoop()

运行

        

三、测试计算器逻辑

5+2=

2+2*4=

1+3+56=

        

1111+2222=

        

9/3=

        

123123123 C

        

还可以做很多测试,有很多BUG

不过本文结束啦

代码打包下载路径

wxFormBuilder+wxPython+Python实现的简易计算器小项目代码-Python文档类资源-CSDN下载

总结

以上是生活随笔为你收集整理的wxFormBuilder + wxPython手撸丑陋计算器的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。