一、介绍
官网:https://wxpython.org/
安装:pip install -U wxPython
二、创建应用程序
应用程序对象管理主事件循环,主事件循环时wxPython程序的动力,如果没有应用程序对象,wxPython应用程序将不能运行。
顶级窗口通常用于管理最重要的数据,控制并呈现给用户。
2.1 创建一个wx.App的子类
步骤:
1.定义子类
2.在这个子类中写一个OnInit() 初始化方法
3.在程序的主要部分创建这个类的一个实例
4.调用应用程序实例的MainLoop() 方法
import wx ##导入wxPythonclass App(wx.App):def OnInit(self): ##初始化方法frame = wx.Frame(parent=None,title="Hello wxPython! ") ##创建窗口frame.Show() ##显示窗口return True ##返回值if __name__ == "__main__":app = App() ##调用APP类的实例app.MainLoop() ##调用APP类的MainLoop()主循环方法
2.2 直接使用wx.App
通常,如果在系统中只有一个窗口的话,可以不创建wx.App子类,直接使用wx.App,这个类提供了一个最基本的OnInit() 初始化的方法。
import wx ##导入wxPythonapp = wx.App() ##初始化wx.App类frame = wx.Frame(None,title="Hello wxPython !") ##定义一个顶级窗口frame.Show() ##显示窗口app.MainLoop() ##调用wx.App类的MainLoop() 主循环方法

2.3 使用wx.Frame框架
在GUI中,框架也称为窗口,框架是一个容器,用户可以将它在屏幕上任意移动,并可将它进行缩放,通常包含标题栏、菜单等。
在wxPython中,wx.Frame是所有框架的父类,当用户创建wx.Framw的子类的时候,子类应该调用其父类的构造器wx.Frame.init()。
wx.Frmae的构造器语法格式:wx.Frame(parent,id = 1,title= " ",pos = wx.DefaultPosition,size = wx.DefaultSize,style=wx.DEFAULT_FRAME_STYLE,name = "frame")
parent:框架的父窗口,如果是顶级窗口,这个值是None
id:关于新窗口的wxPythonID号,通常设置为-1,让wxPython自动生成一个新的ID
title:窗口的标题
pos:一个wx.Point对象,它指定这个新窗口的左上角在屏幕中的位置,在图形用户界面程序中,通常(0,0)是显示器的左上角。默认为(-1,-1)让系统决定窗口的位置
size:一个wx.Size对象,它指定这个窗口的初始尺寸,这个默认的(-1,-1) 将让系统决定窗口的初始尺寸
style:指定窗口的类型的变量,可以使用或运算来组合它们
name:框架的内在的名字,可以使用它来寻找这个窗口
##使用wx.Frame 框架import wx ##导入wxPythonclass MyFrame(wx.Frame):def __init__(self,parent,id):wx.Frame.__init__(self,parent,id,title="创建 Frame",pos= (100,100),size =(300,300))if __name__ == "__main__":app = wx.App() ##初始化应用frame = MyFrame(parent = None,id=1) ##实例MyFrame类,并传递参数frame.Show() ##显示窗口app.MainLoop() ##调用MainLoop()主循环方法
三、常用控件
3.1 StaticText 文本类
wx.StaticText类来完成屏幕上绘制纯文本
语法: wx.StaticText(parnet,id,label,pos=wx.DefaulPosition,size=wx.DefaultSize,style=0,name="StaticText"
parent:父窗口部件
id:标识符,使用-1可以自动创建一个唯一的标识
label:显示在静态控件中的文本内容
pos:一个wx.Point对象或一个python元组,窗口部件的位置
size:一个wx.Size对象或一个python元组,窗口部件的大小
style:样式标记
name:对象的名字
设置字体的语法wx.font(pointSize,family,style,weight,underline=Flase,faceNme="",enconding = wx.FONTENCONDING_DEFAULT)
pointSize:字体的整数尺寸,单位为磅
family:用于快速指定一个字体而无须知道该字体的实际名字
style:指明字体是否倾斜
weight:指明字体的醒目程度
underline:只在windows下面有效,值为True,加下划线,值为False,不加下划线
faceNme:指定字体名
enconding:指定编码方式,不指定为默认编码方式
##静态文本输出import wxclass MyFrame(wx.Frame):def __init__(self, parent,id):wx.Frame.__init__(self, parent,id,title = '创建静态文本类',pos = (100,100),size =(600,450))panel = wx.Panel(self) ##创建画板##创建标题,并设置字体title = wx.StaticText(panel,label ="Python 之禅 ----Tim Peters",pos=(100,20))font = wx.Font(16,wx.DEFAULT,wx.FONTSTYLE_NORMAL,wx.NORMAL)title.SetFont(font)##创建文本wx.StaticText(panel,label ="Beautiful is better than ugly.",pos=(50,50))wx.StaticText(panel,label ="Explicit is better than implicit.",pos=(50,70))wx.StaticText(panel,label ="Simple is better than complex.",pos=(50,90))wx.StaticText(panel,label ="Complex is better than complicated.",pos=(50,110))wx.StaticText(panel,label ="Flat is better than nested.",pos=(50,130))wx.StaticText(panel,label ="Sparse is better than dense.",pos=(50,150))wx.StaticText(panel,label ="Readability counts.",pos=(50,170))wx.StaticText(panel,label ="Special cases aren't special enough to break the rules.",pos=(50,190))wx.StaticText(panel,label ="Although practicality beats purity.",pos=(50,210))wx.StaticText(panel,label ="Errors should never pass silently.",pos=(50,230))wx.StaticText(panel,label ="Unless explicitly silenced.",pos=(50,250))wx.StaticText(panel,label ="In the face of ambiguity, refuse the temptation to guess.",pos=(50,270))wx.StaticText(panel,label ="There should be one-- and preferably only one --obvious way to do it.",pos=(50,290))wx.StaticText(panel,label ="Although that way may not be obvious at first unless you're Dutch.",pos=(50,310))wx.StaticText(panel,label ="If the implementation is hard to explain, it's a bad idea.",pos=(50,330))wx.StaticText(panel,label ="If the implementation is easy to explain, it may be a good idea.",pos=(50,350))wx.StaticText(panel,label ="Namespaces are one honking great idea -- let's do more of those!",pos=(50,370))if __name__ == "__main__":app= wx.App() #初始化应用frame = MyFrame(parent=None,id = -1) #实例化MyFrame类,并传递参数frame.Show() #显示窗口app.MainLoop() #调用主循环方法
3.2 TextCtrl输入文本类
wx.TextCtrl类允许输入单行和多行文本,也可以作为密码输入控件。
语法格式:wx.TextCtrl(parant,id,vlaue="",pos=wx.DefaultPosition,size=wx.DefaultSize,style=0,validator=wx.DefaultValidatorname=wx.TextCtrlNameStr)
style:单行wx.TextCtrl的格式
- wx.TE_CENTER:控件中的文本居中- wx.TE_LEFT:控件中的文本左对齐,默认行为。- wx.TE_NOHIDESEL:文本始终高亮显示,只适用于Windows。- wx.TE_PASSWORD:不显示所键入的文本,代替以星号显示。- wx.TE_PROCESS_ENTER:如果使用了这个样式,那么当用户在控件内按下回车
键时,一个文本输入事件被触发。否则,按键事件内在的由该文本控件或该对话框管
理
- wx.TE_PROCESS_TAB:如果指定了这个样式,那么通常的字符事件在Tab键按下
时创建(一般意味一个制表符将被插入文本)。否则,tab由对话框来管理,通常是
控件间的切换
- wx.TE_READONLY:文本控件为只读,用户不能修改其中的文本。- wx.TE_RIGHT:控件中的文本右对齐。
vlaue:显示在该控件中的初始文本
validator:常用于过滤数据以确保只能输入要接收的数据
import wxclass MyFrame(wx.Frame):def __init__(self, parent,id):wx.Frame.__init__(self, parent,id,title="创建TextCtrl类",size = (400,300))#创建面板panel = wx.Panel(self)#创建文本和输入框self.title = wx.StaticText(panel,label ="请输入用户名和密码",pos = (140,20))self.label_user = wx.StaticText(panel,label ="用户名",pos = (50,50))self.text_user = wx.TextCtrl(panel,pos = (100,50),size =(235,25),style = wx.TE_LEFT)self.label_password = wx.StaticText(panel,label="密码",pos = (50,90))self.text_password = wx.TextCtrl(panel,pos = (100,90),size =(235,25),style = wx.TE_PASSWORD)if __name__ == "__main__":app = wx.App() ##初始化应用frame = MyFrame(parent = None,id = 1) ##实例化MyFrame类,并传递参数frame.Show() ##显示窗口app.MainLoop() ##调用主循环方法
3.3 Button 按钮类
按钮用于捕获用户生成的单击事件,用于触发绑定的处理函数。
语法:wx.Button(parent, id, label, pos, size=wxDefaultSize, style=0,validator, name="button")
import wxclass MyFrame(wx.Frame):def __init__(self, parent,id):wx.Frame.__init__(self, parent,id,title="创建TextCtrl类",size = (400,300))#创建面板panel = wx.Panel(self)#创建文本和输入框self.title = wx.StaticText(panel,label ="请输入用户名和密码",pos = (140,20))self.label_user = wx.StaticText(panel,label ="用户名",pos = (50,50))self.text_user = wx.TextCtrl(panel,pos = (100,50),size =(235,25),style = wx.TE_LEFT)self.label_password = wx.StaticText(panel,label="密码",pos = (50,90))self.text_password = wx.TextCtrl(panel,pos = (100,90),size =(235,25),style = wx.TE_PASSWORD)##创建确定和取消按钮self.bt_confirm = wx.Button(panel,pos = (105,130),label="确定")self.bt_cancel = wx.Button(panel,pos = (195,130),label="取消")if __name__ == "__main__":app = wx.App() ##初始化应用frame = MyFrame(parent = None,id = 1) ##实例化MyFrame类,并传递参数frame.Show() ##显示窗口app.MainLoop() ##调用主循环方法
四、Sizer
sizer是用于自动布局一组窗口控件的算法,属于一个容器窗口,每个不同的sizer基于一套规则管理它的窗口的尺寸和位置。
创建一个siezer的步骤:
1.创建用来自动调动尺寸的panel或container(容器)
2.创建sizer
3.创建子窗口
4.使用sizer的Add() 方法来将每个子窗口添加到sizer,并添加sizer的附加信息,eg:窗口周围控件的度量,如何对齐窗口,当容器窗口改变大小的时候如何拓展子窗口
5.sizer可以嵌套,可以添加别的sizer到父sizer中
6.调用容器的SetSizer(sizer)方法
常用的wxPython的sizer
| sizer名称 | 描述 |
|---|---|
| BoxSizer | 在一条线上的窗口部件的布局,可以是水平或垂直的 当尺寸改变的时候,控制窗口部件的行为上很灵活,通常用于嵌套的样式 |
| FlexGridSizer | 网格布局,行和列所在行或列的最大元素分别被设置 |
| GridSizer | 网格布局,每个元素都有相同的尺寸 项目被从左到右添加,直到一行被填满,然后从下一行开始 |
| GridBagSizer | 网格布局,允许项目被放置在网格上的特定点,也允许项目跨越多个网格区域 |
| StaticBoxSizer | 等同于wx.BoxSizer,多了一个边框,带有标题和环线 |
4.1 box sizer
box sizer是wxPython提供的sizer中的最简单和最灵活的sizer。
一个box sizer是一个垂直列或水平行,窗口部件在其中从左至右或从上到下布置在一条线上。
实例
#使用BoxSizer布局import wxclass MyFrame(wx.Frame):def __init__(self, parent,id):wx.Frame.__init__(self, parent,id,'用户登录',size = (400,300))##创建面板panel = wx.Panel(self)self.title = wx.StaticText(panel,label ="请输入用户名和密码")#添加容器vsizer = wx.BoxSizer(wx.VERTICAL) ##创建了一个wx.BoxSizervsizer.Add(self.title,proportion=0,flag=wx.BOTTOM|wx.TOP|wx.ALIGN_CENTER,border = 15) ##设置增加背景控件,panel.SetSizer(vsizer)if __name__ == "__main__":app = wx.App() ##初始化frame = MyFrame(parent=None,id=-1) ##实例MyFrame,并传递参数frame.Show() ##显示窗口app.MainLoop() ##调用主循环方法

Add() 使用语法
Box.Add(control,propotion,flag,border)
control:要添加的控件
proportion:所添加控件在定义的定位方式所代表方向上占据的控件比例。
flag:flag参数与border参数结合使用可以指定边距宽度
- wx.LFET:左边距- wx.RIGHT:右边距- wx.BOTTOM:下边距- wx.TOP:上边距- wx.ALL:上下左右四个边距- wx.ALIGN_LFET:左边对齐- wx.ALIGN_RIGHT:右边对齐- wx.ALIGN_TOP:顶部对齐- wx.ALIGN_BOTTOM:底边对齐- wx.ALIGN_CENTER_VERTICAL:垂直对齐- wx.ALIGN_CENTER_HORIZONTAL:水平对齐- wx.ALIGN_CENTER:居中对齐- wx.EXPAND:所添加控件将占有sizer定位方向上所有可用的空间- boder:控制所添加控件的边距
实现用户登录界面
##实现用户登录界面import wxclass MyFrame(wx.Frame):def __init__(self,parent,id):wx.Frame.__init__(self,parent,id,'用户登录',size=(400,300))##创建面板panel = wx.Panel(self)##创建"确定”和“取消”按钮self.bt_button = wx.Button(panel,label="确定")self.cacel_button = wx.Button(panel,label="取消")##创建“文本,左对齐self.static_Text = wx.StaticText(panel,label="请输入用户名和密码")self.Suser_Text = wx.StaticText(panel,label="用户名")self.user_Text = wx.TextCtrl(panel,style=wx.TE_LEFT)self.Spass_Text = wx.StaticText(panel,label="密码")self.pass_Text = wx.TextCtrl(panel,style= wx.TE_PASSWORD,)##添加容器,容器中控件横向对齐hsizer_user = wx.BoxSizer(wx.HORIZONTAL)hsizer_user.Add(self.Suser_Text,proportion=0,flag=wx.ALL,border=5)hsizer_user.Add(self.user_Text,proportion=1,flag=wx.ALL,border=5)hsizer_pass = wx.BoxSizer(wx.HORIZONTAL)hsizer_pass.Add(self.Spass_Text,proportion=0,flag=wx.ALL,border=5)hsizer_pass.Add(self.pass_Text,proportion=1,flag=wx.ALL,border=5)hsizer_Button = wx.BoxSizer(wx.HORIZONTAL)hsizer_Button.Add(self.bt_button,proportion=0,flag=wx.ALIGN_CENTER,border=5)hsizer_Button.Add(self.cacel_button,proportion=1,flag=wx.ALIGN_CENTER,border=5)##添加容器,容器中控件纵向对齐vsizer_all = wx.BoxSizer(wx.VERTICAL)vsizer_all.Add(self.static_Text,proportion=0,flag=wx.ALIGN_CENTER|wx.TOP|wx.BOTTOM,border=15)vsizer_all.Add(hsizer_user,proportion=1,flag=wx.LEFT|wx.RIGHT|wx.EXPAND,border=45)vsizer_all.Add(hsizer_pass,proportion=2,flag=wx.LEFT|wx.RIGHT|wx.EXPAND,border=45)vsizer_all.Add(hsizer_Button,proportion=3,flag=wx.ALIGN_CENTER|wx.TOP,border=15)panel.SetSizer(vsizer_all)if __name__ == "__main__":app = wx.App()frame = MyFrame(parent=None,id=-1)frame.Show()app.MainLoop()
五、事件处理
事件(event)是指应用程序期间发生的时候,要求有一个响应。
事件处理器(event hander):响应事件时所调用的函数或方法。
事件绑定器(event binder):封装了特定窗口部件、特定事件类型和一个事件处理器的wxPython对象。
编写事件处理器语法:self.Bind(wx.EVT_BUTTON, self.OnClick, aButton)
Bind() 方法是wx.EvtHandle的一个方法,声明为按钮事件类型
self.OnClick是方法名


##实现用户登录界面import wxclass MyFrame(wx.Frame):def __init__(self,parent,id):wx.Frame.__init__(self,parent,id,'用户登录',size=(400,300))##创建面板panel = wx.Panel(self)##创建"确定”和“取消”按钮self.bt_button = wx.Button(panel,label="确定")self.bt_button.Bind(wx.EVT_BUTTON,self.OnClickBt)self.cacel_button = wx.Button(panel,label="取消")self.cacel_button.Bind(wx.EVT_BUTTON,self.OnClickCancel)##创建“文本,左对齐self.static_Text = wx.StaticText(panel,label="请输入用户名和密码")self.Suser_Text = wx.StaticText(panel,label="用户名")self.user_Text = wx.TextCtrl(panel,style=wx.TE_LEFT)self.Spass_Text = wx.StaticText(panel,label="密码")self.pass_Text = wx.TextCtrl(panel,style= wx.TE_PASSWORD,)##添加容器,容器中控件横向对齐hsizer_user = wx.BoxSizer(wx.HORIZONTAL)hsizer_user.Add(self.Suser_Text,proportion=0,flag=wx.ALL,border=5)hsizer_user.Add(self.user_Text,proportion=1,flag=wx.ALL,border=5)hsizer_pass = wx.BoxSizer(wx.HORIZONTAL)hsizer_pass.Add(self.Spass_Text,proportion=0,flag=wx.ALL,border=5)hsizer_pass.Add(self.pass_Text,proportion=1,flag=wx.ALL,border=5)hsizer_Button = wx.BoxSizer(wx.HORIZONTAL)hsizer_Button.Add(self.bt_button,proportion=0,flag=wx.ALIGN_CENTER,border=5)hsizer_Button.Add(self.cacel_button,proportion=1,flag=wx.ALIGN_CENTER,border=5)##添加容器,容器中控件纵向对齐vsizer_all = wx.BoxSizer(wx.VERTICAL)vsizer_all.Add(self.static_Text,proportion=0,flag=wx.ALIGN_CENTER|wx.TOP|wx.BOTTOM,border=15)vsizer_all.Add(hsizer_user,proportion=1,flag=wx.LEFT|wx.RIGHT|wx.EXPAND,border=45)vsizer_all.Add(hsizer_pass,proportion=2,flag=wx.LEFT|wx.RIGHT|wx.EXPAND,border=45)vsizer_all.Add(hsizer_Button,proportion=3,flag=wx.ALIGN_CENTER|wx.TOP,border=15)panel.SetSizer(vsizer_all)##单击确定的事件处理def OnClickBt(self,event):message = " "username = self.user_Text.GetValue() ##获取输入的用户名password = self.pass_Text.GetValue() ##获取输入的密码if username == "" or password == "":message ='用户名或密码不能为空'elif username == 'lhuan' and password == 'lhuan':message = '登录成功'else:message = '用户名和密码不匹配'wx.MessageBox(message)##单击取消的事件处理def OnClickCancel(self,event):self.user_Text.SetValue("") ##清空输入的用户名self.pass_Text.SetValue("") ##清空输入的密码if __name__ == "__main__":app = wx.App()frame = MyFrame(parent=None,id=-1)frame.Show()app.MainLoop()
