此篇中,介绍的是个第三方库,而该库的书籍,Creating GUI Applications with wxPython Kindle Edition, 358 pages,完全是把一个前端教程缩减到一章中,所以内容不连贯、缺少很多内容,但一个没有GUI的程序,只能很简单的使用,所以GUI非常需要。而之后几章介绍的是网络编程和人工智能,所以这章结束后,真的要停下巩固下,做几个完善的应用。
前端是不是并不算真正的程序员? - 朱富贵的回答 - 知乎
目前基于Python的图形用户界面(Graphical User Interface,GUI)程序开发库又多个,如Tkinter、PyQt、wxPython等库。其中Tkinter库是基于Python的标准GUI工具包接口,PyQt库是Python和Qt库的成功融合。Tkinter库和Jython相比,wxPython库是一个开源、跨平台、支持GUI程序开发的第三方库,允许Python程序员方便的创建完整、功能健全的GUI程序。
wxPython-4.1.1-cp39-cp39-win_amd64.whl (18.1 MB)
Pillow-8.0.1-cp39-cp39-win_amd64.whl (2.1 MB)
import wx
#创建App对象
app=wx.App()
#创建并设置Frame窗体
frame=wx.Frame(None,title="第1个wxPython程序",size=(300,150))
#创建面板,添加到窗体frame中
panel=wx.Panel(frame)
#创建、设置标签,添加到面板panel中
sTxt_info=wx.StaticText(panel,label="欢迎来到Python世界!",pos=(60,40))
#显示窗体
frame.Show(True)
#启动app.MainLoop()方法,进入循环
app.MainLoop()
Mainloop:Execute the main GUI event loop 执行主GUI事件循环
事件循环就是将要执行的事件从栈里一个个的读取执行,这个一个个就是循环过程,直至栈空,再无事件。
可以理解为执行上述app的操作。
使用wxPython建立GUI程序的步骤如下
(1)导入wx模块
import wx
(2)创建一个wx.App实例
app=wx.App()
(3)创建一个顶层窗体
frame=wx.Frame(None)
(4)显示窗体
frame.Show(True)
(5)进入应用程序循环,等待处理事件
app.MainLoop()
事件处理是wxPython程序工作的基本机制
1、事件和事件处理机制
事件指发生在系统中的事,应用程序通过触发相应的功能对他进行响应。事件可以是低级的用户动作,如鼠标移动、键盘按下等;也可以是高级的用户动作,如单击按钮、选中列表框选项等;也可能是其他方式,如网络连接、定时器等。
wxPython程序中与事件和事件处理相关的主要概念如下:
(1)事件(Event):在应用程序期间发生的事,要求有一个相应
(2)事件对象(Event Object):代表一个事件,其中包括事件的数据等属性,是类wx.Event或其子类的对象,子类如wx.CommandEvent和wx.MouseEvent
(3)事件类型(Event Type):分配给每个事件对象的一个整数ID,如wx.MouseEvent的事件类型标识了该事件是一个鼠标单击还是一个鼠标移动
(4)事件源(Event Source):能产生事件的任何wxPython对象,如按钮、菜单、列表框等控件
(5)事件处理器(Event Handler):响应事件调用的方法,也称为处理器方法
(6)事件绑定器(Event Binder):一个封装了特定控件、特定事件类型和一个事件处理器的wxPython对象,为了被调用,所有事件处理器必须用一个事件绑定器注册
(7)wx.EvtHandler(事件处理者):其对象在一个特定类型、一个事件源和一个事件处理器之间创建绑定
wxPython应用程序将特定类型的事件和特定的代码相关联进行工作,该代码在响应事件时执行,事件被映射到代码的过程称为事件处理。和大多数GUI程序相似,wxPython程序采用基于事件的驱动机制
2、事件绑定
事件绑定器有wx.PyEventBinder的对象组成。事件绑定器的对象名字是全局性的,以wx.EVT_开头。wxPython中有各种不同类型的事件绑定器,用于将不同类型的控件和一个事件对象、一个处理器方法连接起来,使wxPython程序能够通过执行处理器方法中的代码响应控件上的事件。
绑定控件事件可使用wx.evtHandler的Bind()方法,其常用格式如下:
self.Bind(eventBinder,handler,sourceCtrl)或
self.sourceCtrl.Bind(eventBinder,handler)
其中,eventBinder为事件绑定器。Handler是一个可调用wxPython的对象,通常是一个被绑定的事件处理方法。sourceCtrl是产生该事件的源控件
在标签中实时显示鼠标在窗体中的坐标
import wx
#创建窗体类,继承wx.Frame
class MyFrame(wx.Frame):
#定义构造方法
def __init__(self):
#调用父类构造方法,设置窗体参数
wx.Frame.__init__(self,None,-1,"事件处理示例",size=(300,150))
panel=wx.Panel(self,-1) #创建面板
panel.Bind(wx.EVT_MOTION,self.OnMove) #绑定事件
#创建标签
self.sTxt_pos=wx.StaticText(panel,-1,"",pos=(70,30),size=(160,40))
#创建字体并设置为标签self.sTxt_pos的字体
font=wx.Font(20,wx.DECORATIVE,wx.NORMAL,wx.BOLD)
self.sTxt_pos.SetFont(font)
#鼠标移动事件处理方法
def OnMove(self,event):
pos=event.GetPosition() #返回鼠标坐标位置
self.sTxt_pos.SetLabel("%s:%s"%(pos.x,pos.y)) #显示鼠标坐标位置
if __name__=='__main__':
app=wx.App(False)
MyFrame().Show(True) #创建窗体对象,显示窗体
app.MainLoop()
wxPython提供了丰富的空间,如窗体、按钮、标签、文本框、列表框,使Python程序员能够轻松的创建见状、功能强大的GUI程序
窗体(wx.Frame)是一个容器,可移动、缩放,可包含菜单、工具栏等,是所有窗体的父类,使用窗体时一般需要派生出子类。创建一个窗体时需要调用父类的构造方法设置参数,格式如下:
wx.Frame.__init__(parent,id,title,pos,size,style)
parent:窗体的父容器。如果窗体为顶级窗体,则parent的值为None
id:窗体的wxPython ID
title:窗体标题
pos:窗体左上角在屏幕中的位置,是元祖类型数据
size:为窗体的初始尺寸,是元祖类型数据
style:窗体样式,如wx.CAPTION、wx.CLOSE_BOX
wx.Frame的常用方法
(1)Centre:设置窗体显示在屏幕中间
(2)SetPosition(x,y):设置窗体在屏幕中的显示位置(x,y)
(3)SetSize((width,height)):设置窗体的大小(width,height)
(4)SetTitle(title):设置窗体的标题title
wx.Frame的常用事件绑定器
(1)wx.EVT_CLOSE:单击窗体“关闭”按钮时触发相关处理程序
(2)wx.EVT_MENU_OPEN:菜单刚打开时触发相关处理程序
(3)wx.EVT_MENU_CLOSE:菜单刚关闭时触发相关处理程序
窗体的创建和使用
import wx
#创建窗体类,继承wx.Frame
class MyFrame(wx.Frame):
#定义构造方法
def __init__(self,parent):
#调用父类构造方法,设置窗体参数
wx.Frame.__init__(self,parent,id=-1,title="西游记",size=(340,160))
panel=wx.Panel(self) #创建面板
#创建标签,在标签中写入内容,添加panel中
wx.StaticText(parent=panel,label="混沌未分天地乱,茫茫渺渺无人见。",pos=(70,20))
wx.StaticText(parent=panel,label="自从盘古破鸿蒙,开辟从兹清浊辨。",pos=(70,40))
wx.StaticText(parent=panel,label="覆载群生仰至仁,发明万物皆成善。",pos=(70,60))
wx.StaticText(parent=panel,label="欲知造化会元功,须看西游释厄传。",pos=(70,80))
self.Center() #设置窗体运行初始位置为桌面中间
if __name__=="__main__":
app=wx.App()
MyFrame(None).Show(True)
app.MainLoop()
1、按钮
wxPython中提供了3种不同类型的按钮:wx.Button(简单、传统按钮)、wx.ToggleButton(二状态按钮/开关按钮/选中未选中)、wx.BitmapButton(带有位图的按钮)
创建一个按钮的常用构造方法:
wx.Button(parent,id,label,pos,size,style)
label:按钮上显示的内容
style:按钮样式,wx.BU_TOP、wx.BU_RIGHT等
常用方法:
(1)SetLabel(label):设置按钮上的显示内容label
(2)GetLabel():返回按钮上显示的内容
wx.Button最常用的事件绑定器为wx.EVT_BUTTON
2、标签
wx.StaticText提供了一行或多行的只读文本,通常放置在窗体上,或者作为另一个插件的标识符,或者作为信息串等。
wx.StaticText(parent,id,label,pos,size,style)
3、文本框
wx.TextCtrl用于接收从键盘输入的内容或显示文本信息。
wx.TextCtrl可以是单行、多行或密码字段。
wx.TextCtrl(parent,id,label,pos,size,style)
wx.TextCtrl常用方法:
(1)SetValue(text):设置文本框中的内容text
(2)GetValue():返回文本框中的内容
wx.TextCtrl的常用事件绑定器:
(1)wx.EVT_TEXT:当文本框中的内容发生变化时触发相关处理程序
(2)wx.EVT_TEXT_ENTER:当在文本框中按下Enter键时触发相关处理程序
(3)wx.EVT_TEXT_MAXLEN:当文本框中的文本长度达到指定最大值时触发相关处理程序
【例】使用按钮、标签和文本框编写一个求和程序
import wx
class MyFrame(wx.Frame):
def __init__(self,superion):
wx.Frame.__init__(self,parent=superion,title="2个数求和",size=(300,200))
panel=wx.Panel(self) #创建面板
#创建标签
wx.StaticText(parent=panel,label="请输入操作数1:",pos=(30,10))
wx.StaticText(parent=panel,label="请输入操作数2:",pos=(30,50))
wx.StaticText(parent=panel,label="结 果",pos=(30,90))
#创建文本框
self.txt_op1=wx.TextCtrl(parent=panel,pos=(120,10))
self.txt_op2=wx.TextCtrl(parent=panel,pos=(120,50))
self.txt_res=wx.TextCtrl(parent=panel,pos=(120,90),style=wx.TE_READONLY)
#创建按钮并绑定事件
self.btn_Add=wx.Button(parent=panel,label="求和",pos=(70,130))
self.Bind(wx.EVT_BUTTON,self.On_btn_Add,self.btn_Add)
self.btn_Quit=wx.Button(parent=panel,label="退出",pos=(150,130))
self.Bind(wx.EVT_BUTTON,self.On_btn_Quit,self.btn_Quit)
#“求和”按钮事件处理方法
def On_btn_Add(self,event):
op1=int(self.txt_op1.GetValue()) #返回文本框的内容
op2=int(self.txt_op2.GetValue())
sum=op1