前言:前文学习了使用wxPython来创建窗口,并添加了一个静态的文本信息。
学习目标:通过一个简易计算的界面完成下面的学习
- 学习一下如何在窗体上设计文本框控件和按钮控件,
- 通过BoxSizer对控件进行布局设计,
- 将文本框输入信息和按钮单击事件进行关联处理。
目录
🍓2.2、设置前三个文本框的布局及BoxSizer相关设置逻辑和语法
一、设计界面原型
先设计想要实现的界面的布局,原型如下,界面很简单:
🍁界面元素分析:
界面中包含:
- 窗体标题为“简易计算”
- 4个文本框控件 --- wx.TextCtrl
- 1个按钮控件,按钮名字是'OK' --- wx.Button
🍁界面布局分析:
- 前三个文本框水平放置 --- boxsizer1 = wx.BoxSizer(wx.HORIZONTAL)
- 前三个文本框与按钮以及下面那个文本框是垂直放置的 --- boxsizer2 = wx.BoxSizer(wx.VERTICAL)(包含boxsizer1,一个按钮,一个文本框)
二、界面设计实现
🍓2.1、窗体初始化
在进行控件设计之前,可以先将窗体的基础搭建起来,然后后续控件在慢慢往里填,基本流程如下:
- 定义一个应用程序app
- 定义一个窗体
- 定义一个panel容器
- 激活显示窗口
- 运行程序
# 试验2:基于wxpython实现两个数的运算程序
# 导入wx库文件
import wx
# 进行应用程序和窗体的初始化
# 定义一个应用程序
app = wx.App()
# 定义一个窗体
window = wx.Frame(None, title='简易计算', size=(500, 400))
# 定义一个容器
panel = wx.Panel(window)
# 激活显示窗口
window.Show(True)
# 运行程序
app.MainLoop()
运行结果如下:
🍓2.2、设置前三个文本框的布局及BoxSizer相关设置逻辑和语法
文本框的定义是调用wx.TextCtrl,三个文本框就调用三次:
- num1 = wx.TextCtrl(panel)
- operator = wx.TextCtrl(panel)
- num2 = wx.TextCtrl(panel)
控件布局设计是调用wx,BoxSizer,基本流程有三步:
- 定义wx.BoxSizer是水平排列还是垂直排列,什么都不加的话默认是水平排列
- 水平排列:wx.HORIZONTAL
- 垂直排列:wx.VERTICAL
- 依次将控件加入到上面定义的boxsizer中,并指定控件参数属性,boxsizer1.Add(控件名, proportion=0, border=8, flag=wx.LEFT)
- proportion:控件大小,默认为0
- border:边界大小,单位为像素
- flag:标志,一般有上下左右,扩展,多个属性用 ' | ' 隔开就好了,wx.LEFT | wx.RIGHT | wx.TOP | wx.BOTTOM | wx.EXPAND
- 执行布局设置,在将控件布局好之后一定要调用方法执行一下,panel.SetSizer(boxsizer名字)
代码设计如下:
# 试验2:基于wxpython实现两个数的运算程序
# 导入wx库文件
import wx
# 进行应用程序和窗体的初始化
# 定义一个应用程序
app = wx.App()
# 定义一个窗体
window = wx.Frame(None, title='简易计算', size=(500, 400))
# 定义一个容器
panel = wx.Panel(window)
# 定义四个文本框,一个按钮
num1 = wx.TextCtrl(panel)
operator = wx.TextCtrl(panel)
num2 = wx.TextCtrl(panel)
# 设置前三个文本框的布局
# 1、定义BoxSizer
boxsizer1 = wx.BoxSizer(wx.HORIZONTAL) # 水平排列,不加的话默认就是水平排列
# 2、依次加入控件到boxsizer中
boxsizer1.Add(num1, proportion=0, border=8, flag=wx.LEFT) # proportion:控件大小,默认为0
boxsizer1.Add(operator, proportion=1, border=8, flag=wx.LEFT) # flag:标志,一般有上下左右,扩展
boxsizer1.Add(num2, proportion=0, border=8, flag=wx.LEFT | wx.RIGHT) # border:边界大小,单位为像素
# 执行布局设置
panel.SetSizer(boxsizer1)
# 激活显示窗口
window.Show(True)
# 运行程序
app.MainLoop()
运行结果如下:
🍓2.3、设置垂直排列的控件
按钮的定义是调用wx.Button,用label来定义按钮的名字:button = wx.Button(panel, label="OK")
再定义一个boxsizer2用来声明是垂直排列。
基本流程和上面一样,不一样的是在执行布局设置时,我们需要改成boxsizer2,因为boxsizer1已经包含在了boxsizer2中了。
代码设计如下:
# 试验2:基于wxpython实现两个数的运算程序
# 导入wx库文件
import wx
# 进行应用程序和窗体的初始化
# 定义一个应用程序
app = wx.App()
# 定义一个窗体
window = wx.Frame(None, title='简易计算', size=(500, 400))
# 定义一个容器
panel = wx.Panel(window)
# 定义四个文本框,一个按钮
num1 = wx.TextCtrl(panel)
operator = wx.TextCtrl(panel)
num2 = wx.TextCtrl(panel)
result = wx.TextCtrl(panel)
button = wx.Button(panel, label="OK")
# 设置前三个文本框的布局
# 1、定义BoxSizer
boxsizer1 = wx.BoxSizer(wx.HORIZONTAL) # 水平排列,不加的话默认就是水平排列
# 2、依次加入控件到boxsizer中
boxsizer1.Add(num1, proportion=0, border=8, flag=wx.LEFT) # proportion:控件大小,默认为0
boxsizer1.Add(operator, proportion=1, border=8, flag=wx.LEFT) # flag:标志,一般有上下左右,扩展
boxsizer1.Add(num2, proportion=0, border=8, flag=wx.LEFT | wx.RIGHT) # border:边界大小,单位为像素
# 再定义一个boxsizer, 垂直排列
boxsizer2 = wx.BoxSizer(wx.VERTICAL) # 垂直排列
# 把boxsizer1加入boxsizer2
boxsizer2.Add(boxsizer1, flag=wx.EXPAND | wx.TOP, border=8) # expand扩展平铺
boxsizer2.Add(button, flag=wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, border=8)
boxsizer2.Add(result, proportion=1, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP | wx.BOTTOM, border=8)
# 执行布局设置
panel.SetSizer(boxsizer2)
# 激活显示窗口
window.Show(True)
# 运行程序
app.MainLoop()
运行结果如下:
🍓2.4、将界面出入数据与按钮单击事件进行关联处理
实现目标1:接收第一个文本框num1中的输入数据,在单击‘OK’按钮之后,在result文本框中显示输入的数据。
实现流程:
- 定义一个按钮事件函数 def click(event),event不能省!
- 用GetValue方法获取num1中的输入数据:number1 = num1.GetValue()
- 用SetValue方法把对应的数据设置在结果文本框中:result.SetValue(number1)
- 将按钮控件和事件函数进行绑定:button.Bind(wx.EVT_BUTTON, click)
这样两步之后点击单击按钮就会在结果文本框中显示num1的输入数据了,代码如下:
def click(event): # event不能省
# 获取num1中的输入数据
number1 = num1.GetValue()
# 将获取的数据放入结果文本框中
result.SetValue(number1)
# 进行按钮事件绑定
button.Bind(wx.EVT_BUTTON, click)
实现目标2:实现加减乘除简易计算
实现流程:基本流程如上。
🍓2.5、简易计算完整代码
# 试验2:基于wxpython实现两个数的运算程序
# 导入wx库文件
import wx
# 定义按钮触发事件函数
def calculator(event): # event不能省
# 获取num1中的输入数据
number1 = num1.GetValue()
# 获取operator中输入的运算符
oper = operator.GetValue()
# 获取num2中的输入数据
number2 = num2.GetValue()
if oper == "+":
r = int(number1) + int(number2)
if oper == "-":
r = int(number1) - int(number2)
if oper == "*":
r = int(number1) * int(number2)
if oper == "/":
r = float(number1) / int(number2)
# 将获取的数据放入结果文本框中
result.SetValue(number1 + oper + number2 + "=" + str(r))
# 进行应用程序和窗体的初始化
# 定义一个应用程序
app = wx.App()
# 定义一个窗体
window = wx.Frame(None, title='简易计算', size=(500, 400))
# 定义一个容器
panel = wx.Panel(window)
# 定义四个文本框,一个按钮
num1 = wx.TextCtrl(panel)
operator = wx.TextCtrl(panel)
num2 = wx.TextCtrl(panel)
result = wx.TextCtrl(panel)
button = wx.Button(panel, label="OK")
# 设置前三个文本框的布局
# 1、定义BoxSizer
boxsizer1 = wx.BoxSizer(wx.HORIZONTAL) # 水平排列,不加的话默认就是水平排列
# 2、依次加入控件到boxsizer中
boxsizer1.Add(num1, proportion=0, border=8, flag=wx.LEFT) # proportion:控件大小,默认为0
boxsizer1.Add(operator, proportion=1, border=8, flag=wx.LEFT) # flag:标志,一般有上下左右,扩展
boxsizer1.Add(num2, proportion=0, border=8, flag=wx.LEFT | wx.RIGHT) # border:边界大小,单位为像素
# 再定义一个boxsizer, 垂直排列
boxsizer2 = wx.BoxSizer(wx.VERTICAL) # 垂直排列
# 把boxsizer1加入boxsizer2
boxsizer2.Add(boxsizer1, flag=wx.EXPAND | wx.TOP, border=8) # expand扩展平铺
boxsizer2.Add(button, flag=wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, border=8)
boxsizer2.Add(result, proportion=1, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP | wx.BOTTOM, border=8)
# 执行布局设置
panel.SetSizer(boxsizer2)
# 进行按钮事件绑定
button.Bind(wx.EVT_BUTTON, calculator)
# 激活显示窗口
window.Show(True)
# 运行程序
app.MainLoop()
运行结果如下:
三、将代码进行类的封装
上面的代码不利于后续的维护,所以还需要对其进行模块化设计,可以分成几个方法:
- 初始化方法:将窗体和控件的创建都在初始化中完成
- 控件布局方法:通过BoxSizer设置界面布局
- 事件函数方法:各种控件对应的事件函数(note:在主函数中不需要调用,因为在调用绑定方法时会自动调用事件方法)
- 控件和事件绑定方法:将控件与对应事件函数进行绑定
- 运行方法:显示窗口和运行程序
将代码以面向对象思想进行结构化设计后,修改如下:
# 使用面向对象思想进行GUI运算器的实现
# 导入相关的类库文件
import wx
# 定义类
class cal_GUI:
# 类的初始化方法,创建所有的控件
def __init__(self):
self.app = wx.App()
self.window = wx.Frame(None, title="简易计算", size=(500, 400))
self.panel = wx.Panel(self.window)
# 创建文本框控件
self.num1 = wx.TextCtrl(self.panel)
self.operator = wx.TextCtrl(self.panel)
self.num2 = wx.TextCtrl(self.panel)
self.result = wx.TextCtrl(self.panel)
# 创建按钮控件
self.button = wx.Button(self.panel, label="OK")
def layout(self):
# 设置一个水平的BoxSizer
boxsizer1 = wx.BoxSizer(wx.HORIZONTAL)
# 把3个文本框加入BoxSizer1中
boxsizer1.Add(self.num1, proportion=0, border=8, flag=wx.LEFT)
boxsizer1.Add(self.operator, proportion=1, border=8, flag=wx.LEFT)
boxsizer1.Add(self.num2, proportion=0, border=8, flag=wx.LEFT | wx.RIGHT)
# 设置一个垂直的BoxSizer
boxsizer2 = wx.BoxSizer(wx.VERTICAL)
# 把按钮和结果文本框以及boxsizer1加入进来
boxsizer2.Add(boxsizer1, border=8, flag=wx.EXPAND | wx.TOP)
boxsizer2.Add(self.button, border=8, flag=wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT)
boxsizer2.Add(self.result, proportion=1, border=8, flag=wx.EXPAND | wx.TOP | wx.BOTTOM | wx.LEFT | wx.RIGHT)
# 执行布局设置
self.panel.SetSizer(boxsizer2)
def cal_event(self, event):
# 获取控件中输入的内容
number1 = self.num1.GetValue()
oper = self.operator.GetValue()
number2 = self.num2.GetValue()
# 根据运算符进行运算处理
if oper == "+":
r = int(number1) + int(number2)
if oper == "-":
r = int(number1) - int(number2)
if oper == "*":
r = int(number1) * int(number2)
if oper == "/":
r = float(number1) / int(number2)
# 将获取的数据放入结果文本框中
self.result.SetValue(number1 + oper + number2 + "=" + str(r))
# 将按钮和对应时间函数进行绑定
def bind_set(self):
self.button.Bind(wx.EVT_BUTTON, self.cal_event)
def run(self):
# 激活显示窗口
self.window.Show(True)
# 运行程序
self.app.MainLoop()
if __name__ == '__main__':
calObj = cal_GUI()
calObj.layout()
calObj.bind_set()
calObj.run()