通过Tkinter模块,可以进行简单的图像界面开发,但是我们可以发现很多人在开发的时候还会选择wxPython模块,它是一个比较成熟且特性比较丰富的模块,它和Tkinter类似,也要引入窗口、按钮、文本框等内容,但是又有它独特的用法。下图为程序与窗口的关系:

然后我们通过一个最简单的wxPython程序来对应一下相关结构,代码如下:
import wx
app = wx.App()
win = wx.Frame(None,title = '小程序',size = (300,300))#frame是容器
win.Show()
app.MainLoop()
注意我们导入的时候使用wx两个英文字母,然后第一行的app即我们的应用程序对象,win对应的是一个窗口对象,我们可以在窗口中添加组件或者功能,然后下面的一行是使这个窗口显示,最后一行就是主事件循环,运行结果如下:

初始化
上面提到的例子就是我们使用wxPython的基本架构,如果我们在程序开发的时候,使用类与对象的关系会更方便我们后期的处理。
我们创建子类的时候首先定义一个子类,然后创建一个OnInit()方法来初始化这个子类,最后在主程序中调用这个类,然后进入主事件循环。
代码如下:
| 1 2 3 4 5 6 7 8 9 | import wx class App(wx.App): def OnInit(self): window = wx.Frame(parent = None,title = '初始化') window.Show() return True if __name__ == '__main__': app = App() app.MainLoop() |
运行结果为:

这个例子中,我们定义的子类App继承了父类wx.App,然后在子类中创建了一个初始化方法,最后在主程序中创建一个类的实例,再进入主事件循环。
2. Frame框架
我们在创建实例的时候总是要引入Frame框架,它属于一种容器,可以用来存放我们主程序的一些标题和功能区,我们来看一下它的语法结构:
| 1 | wx.Frame(parent,id=-1,title=’’,style=’’,name=’’,pos=wx.DefaultPositon,size=wx.DefaultSize) |
Parent指的是框架所处的位置,也就是父窗口的名字,如果当前为顶级窗口,就用None来代替,id为新窗口的ID号,通常设置为-1,title即窗口的名字,size即窗口的大小,style即窗口的类型,name框架的内部名字,pos为一个对象,指定了这个新窗口在界面中的位置,上面所选的Default为默认参数。
具体使用如下:
| 1 | window = wx.Frame(parent = None,id = -1,title = 'Frame框架',size = (400,400),pos = (2,2)) |
wxPython中的控件全部继承与wx.Control,包含了静态文本、文本输入控件、按钮、列表、滑块、滚动条、复选框等,本节我们来学习一下静态文本和文本输入控件。
1. 静态文本
静态文本就是在上屏幕显示的静态文字,我们使用的是wx.StaticText类来完成,它的语法格式为:
| 1 | wx.StaticText(parent,id,label=’’,pos=wx.DefaultPositon,size=wx.DefaultSize,style=’’,name=’’) |
label为显示在控件中的文本信息,其余的我们在前面都学习过就不再作解释。
其中样式style的取值有:
wx.ALIGN_CENTER:静态文本位于静态文本控件的中心。
wx.ALIGN_LEFT:文本在窗口部件中左对齐。这是默认的样式。
wx.ALIGN_RIGHT:文本在窗口部件中右对齐。
wx.ST_NO_AUTORESIZE:如果使用了这个样式,那么在使用了SetLabel()改变文本之后,静态文本控件不将自我调整尺寸。
我们来使用这种方式来输出一首诗,代码如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import wx class Frame(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, wx.ID_ANY,"静态文本", size =(200, 170)) panel = wx.Panel(self, -1) wx.StaticText(panel, wx.ID_ANY, "春夜喜雨 ——杜甫。", (0, 10),(145, -1),wx.ALIGN_RIGHT) text = wx.StaticText(panel, wx.ID_ANY, "好雨知时节,当春乃发生。", (0, 30),(160, -1),wx.ALIGN_RIGHT) text = wx.StaticText(panel, wx.ID_ANY, "随风潜入夜,润物细无声。", (0,50), (160, -1),wx.ALIGN_RIGHT) text =wx.StaticText(panel, wx.ID_ANY, "野径云俱黑,江船火独明。", (0,70),(160, -1),wx.ALIGN_RIGHT) text =wx.StaticText(panel, wx.ID_ANY, "晓看红湿处,花重锦官城。", (0,90),(160, -1),wx.ALIGN_RIGHT) if __name__ == '__main__': app = wx.App() frame = Frame() frame.Show(True) app.MainLoop() |
输出结果为:

注意我们在使用的时候首先要用wx.Panel方式来创建一个容器,类似于Tkinter中的Frame容器,然后我们在这个容器里放置一些组件。
我们还可以对文字信息进行修饰,使用wx.Font方法,它的语法结构如下:
| 1 | wx.Font(pointSize,fimily,style,weight,underline=True,faceName=’’,encoding=wx.FONTENCODING_DEFAULT) |
pointSize为字体的尺寸,family为字体的名字,style来判定倾斜,weight为宽度,underline为下划线,True有,False为无,faceName为此方法的字体名,encoding为编码方式。
2. 文本输入控件
我们在与程序交互的时候,静态文字是无法获取我们输入的信息,因此我们引入wx.TextCtrl类来获取用户输入的文本内容,它的语法结构为:
| 1 2 | wx.TextCtrl(parent,id,value=’’,pos=wx.DefaultPositon,size=wx.DefaultSize,style,validator=wx.DefaultVali dator,name=’’) |
除了validator为过滤数据外其余的我们在前面都提到过,style在这里功能有所增添,我们介绍再介绍一下。
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:控件中的文本右对齐。
我们使用wx.TextCtrl来实现一个登陆界面。
代码如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import wx class Frame(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, wx.ID_ANY,"登陆", size =(300, 300)) panel = wx.Panel(self, -1) wx.StaticText(panel, wx.ID_ANY, "登录界面", (0, 10),(150, -1),wx.ALIGN_RIGHT) text = wx.StaticText(panel, wx.ID_ANY, "账户", (0, 50),(80, -1),wx.ALIGN_RIGHT) text = wx.StaticText(panel, wx.ID_ANY, "密码", (0, 90),(80, -1),wx.ALIGN_RIGHT) text = wx.TextCtrl(panel, wx.ID_ANY, "", (100,50),(100, 20),wx.ALIGN_LEFT) text = wx.TextCtrl(panel, wx.ID_ANY, "", (100,90),(100, 20),wx.ALIGN_LEFT) if __name__ == '__main__': app = wx.App() frame = Frame() frame.Show(True) app.MainLoop() |
运行结果如图:

wxPython模块(3)-按钮和复选框
点击打开在线编译器,边学边练
1. 按钮
按钮是GUI界面中必不可少的一环,在前面Tkinter中已经介绍过按钮,而且大家对按钮一定不陌生,那么我们直接进行语法的学习,wxPython中按钮的语法结构为:
| 1 | wx.Button(parent,id,label,pos,size,style,validator,name) |
它的相关参数与前面我们使用过的参数大致相同,下面我们使用Button按钮对上一节的登录界面进行修饰,代码如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import wx class Frame(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, wx.ID_ANY,"登陆", size =(300, 250)) panel = wx.Panel(self, -1) wx.StaticText(panel, wx.ID_ANY, "登录界面", (0, 10),(150, -1),wx.ALIGN_RIGHT) self.text = wx.StaticText(panel, wx.ID_ANY, "账户", (0, 50),(80, -1),wx.ALIGN_RIGHT) self.text = wx.StaticText(panel, wx.ID_ANY, "密码", (0, 90),(80, -1),wx.ALIGN_RIGHT) self.text = wx.TextCtrl(panel, wx.ID_ANY, "", (100,50),(100, 20),wx.ALIGN_LEFT) self.text = wx.TextCtrl(panel, wx.ID_ANY, "", (100,90), (100, 20), wx.ALIGN_LEFT) self.button = wx.Button(panel, wx.ID_ANY, "登陆", (70,120),(50, 20),wx.ALIGN_LEFT) self.button = wx.Button(panel, wx.ID_ANY, "注册", (140,120), (50, 20), wx.ALIGN_LEFT) if __name__ == '__main__': app = wx.App() frame = Frame() frame.Show(True) app.MainLoop() |
运行图如下:

2. 复选框和单选按钮
复选框对应前面我们学习过的Tkinter中的check控件,复选框提供多个按钮,可提供同时开关的功能,单选按钮对应Tkinter的radio控件,单选按钮提供多个按钮,但是只能选择其中一个按钮,在wxPython中我们使用wx.CheckBox和wx.RadioButton来创建复选框和单选按钮。
看下面的例子(复选框):
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | import wx class Frame(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, wx.ID_ANY,"复选框", size =(300, 250)) panel = wx.Panel(self, -1) self.box = wx.CheckBox(panel, -1, "Checkbox1", pos=(50, 50), size=(80, 20)) # 创建控件 self.box = wx.CheckBox(panel, -1, "Checkbox2", pos=(50, 70), size=(80, 20)) # 创建控件 self.box = wx.CheckBox(panel, -1, "Checkbox3", pos=(50, 90), size=(80, 20)) # 创建控件 if __name__ == '__main__': app = wx.App() frame = Frame() frame.Show(True) app.MainLoop() |
运行结果如图:

单选框代码如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import wx class MyFrame(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, -1, "选择一种喜欢的运动方式", size=(300, 100)) panel = wx.Panel(self) wx.StaticText(panel, wx.ID_ANY, "选择一种喜欢的运动方式", (0, 10), (200, -1), wx.ALIGN_RIGHT) self.check1 = wx.RadioButton(panel, -1, "打篮球", pos=(60, 40), size=(50, 20), style=wx.RB_GROUP) self.check2 = wx.RadioButton(panel, -1, "打乒乓球", pos=(130, 40), size=(50, 20)) self.check3 = wx.RadioButton(panel, -1, "跑步", pos=(200, 40), size=(50, 20)) if __name__ == "__main__": app = wx.App() frame = MyFrame() frame.Show() app.MainLoop() |
运行图如下:

单选按钮和复选框的使用方式类似,区别在于可不可以多选,这个在我们注册账户,选择信息的时候会经常使用到。
wxPython(4)-布局
我们在图形界面开发的时候往往要面临一个如何布局的问题,一个合理的布局能够把有面积的使用最大化,也能帮助使用者更直观的使用界面,我们使用wxPython的时候可以采用两种布局的形式,一种是前面我们用到的绝对布局,也就是说我们所创建的控件的位置是固定不变的,无论窗口的大小如何变化,绝对布局的子窗口或者控件都是不变的,本节我们学习一种Sizer管理布局,它能帮助我们自动布局一组窗口控件。
WxPython中有八种sizer供我们使用,分别是Sizer、WrapSizer、BoxSizer、GridSizer、FlexGridSizer、GridBagSizer和StaticBoxSzer、StdDialogButtonSizer,我们主要对BoxSizer进行学习。
它的分类如图:

我们在日常使用的时候一般使用BoxSizer、StaticBoxSizer、GridSizer和FlexGridSizer这四种,继承Sizer中的方法。
1. BoxSizer布局
BoxSizer布局是使用的几种布局中最灵活简便的一个,它的排布方式垂直或水平,一般是在创建的时候指定布局的方向。
| 1 2 | my_box = wx.BoxSizer(wx.HORIZINTAL) My_box = wx.BoxSizer(wx.VERTICAL) |
上面的属于水平布局,当括号中为空的时候即默认为水平布局,下面的为垂直方向的布局。
我们往布局中添加控件的时候,使用Add()方法,这个Add方法由wx.Sizer继承而来,它的语法格式为:
| 1 | Add(parent,proportion=0,flag=0,border=0,userData=None) |
这种方式添加到父窗口parent当中。
| 1 | Add(AnotherSizer,proportion=0,flag=0,border=0,userData=None) |
这种方式添加到另外一个布局当中。
| 1 | Add(AnotherSizer,proportion=0,flag=0,border=0,userData=None) |
这种方式创建了一个新的空间。
其中flag为对齐、边框和尺寸参数,border为边框宽度、userData为数据的传输。
flag对齐标志有多种:
| 标志 | 说明 |
| ALIGN_TOP | 顶对齐 |
| wx.ALIGN_LEFT | 左对齐 |
| wx.ALIGN_BOTTOM | 底对齐 |
| wx.ALIGN_RIGHT | 右对齐 |
| wx.ALIGN_CENTER | 居中对齐 |
| wx.ALIGN_CENTER_VERTIAL | 垂直居中对齐 |
| wx.ALIGN_CENTER_HORIZONTAL | 水平居中对齐 |
边框flag标志有:
| 标志 | 说明 |
| wx.TOP | 设置有顶部边框,边框的宽度需要通过Add()方法的border参数设置 |
| wx.BOTTOM | 设置有底部边框 |
| wx.LEFT | 设置有左边框 |
| wx.RIGHT | 设置有右边框 |
| wx.ALL | 设置4面全有边框 |
调整尺寸flag标志:
| 标志 | 说明 |
| wx.EXPAND | 调整子窗口(或控件)完全填满有效空间 |
| wx.SHAPED | 调整子窗口(或控件)填充有效空间,但保存高宽比 |
| wx.FIXED_MINSIZE | 调整子窗口(或控件)为最小尺寸 |
| wx.RESERVE_SPACE_EVEN_IF_HIDDEN | 设置此标志后,子窗口(或控件)如果被隐藏,所占空间保留 |
我们来使用BoxSizer布局来创建一个登陆界面:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | import wx class MyFrame(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, -1, "登录界面", size=(300, 300)) panel = wx.Panel(self)#创建一个画布,然后创建功能区并放到画布上 self.title = wx.StaticText(panel,label = '登陆界面') self.username = wx.StaticText(panel,label = '用户:') self.user_name = wx.TextCtrl(panel,style = wx.TE_LEFT) self.userpassword = wx.StaticText(panel,label = '密码:') self.user_password = wx.TextCtrl(panel,style = wx.TE_PASSWORD) self.button_login = wx.Button(panel,label = '登陆') self.button_register = wx.Button(panel,label = '注册') container_one = wx.BoxSizer(wx.HORIZONTAL) # 创建一个box容器并控制水平排列 container_one.Add(self.username,proportion = 0,flag = wx.ALL,border = 7) container_one.Add(self.user_name,proportion = 1,flag = wx.ALL,border = 7) container_two = wx.BoxSizer(wx.HORIZONTAL) # 创建一个box容器并控制水平排列 container_two.Add(self.userpassword,proportion = 0,flag = wx.ALL,border = 7) container_two.Add(self.user_password,proportion = 1,flag = wx.ALL,border = 7) container_three = wx.BoxSizer(wx.HORIZONTAL) # 创建一个box容器并控制水平排列 container_three.Add(self.button_login,proportion = 0,flag = wx.ALIGN_CENTER,border = 4) container_three.Add(self.button_register,proportion =0,flag = wx.ALIGN_CENTER,border = 4) sizers = wx.BoxSizer(wx.VERTICAL) sizers.Add(self.title,proportion=0,flag=wx.BOTTOM|wx.TOP|wx.ALIGN_CENTER,border=10) sizers.Add(container_one,proportion = 0,flag =wx.EXPAND|wx.LEFT|wx.RIGHT,border=40) sizers.Add(container_two, proportion=0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=40) sizers.Add(container_three, proportion=0, flag=wx.ALIGN_CENTER|wx.TOP, border=10) panel.SetSizer(sizers) if __name__ == "__main__": app = wx.App() frame = MyFrame() frame.Show() app.MainLoop() |
输出结果如图:

对应下图:

在这个例子中,我们主要使用了竖直和水平两种布局,我们首先把用户和输入信息放入一个水平BoxSizer,然后把密码和输入信息放入一个BoxSizer,再把两个按钮放在一个BoxSizer,最后再把四种信息全部放到一个竖直的BoxSizer当中。
2. 总结
布局是我们图形界面开发的重要一环,就好比在建造房子之前是一定要设计好图纸的,所以我们先设计布局再进行页面开发。
wxPython(5)-事件管理
我们设计开发的界面之所以称为用户界面,是因为它能响应使用者的操作,然后执行相关指令,如果设计出来的界面只能够进行浏览阅读,那么只能称之为图片或者可读文本。
在响应使用者的操作之前,我们要来了解几个名词。
1) 事件
事件就是用户执行的动作,例如我们去点击一个按钮,这就是一个事件
2) 事件类型
事件也是有分类的,例如我们点击按钮和松开按钮,这就属于两种类型
3) 事件源
事件由哪些控件控制发生
4) 事件处理者
它是wxPython内部的一个wx.EvtHandler子类中的一个方法。
理解了这几个概念,下面我们开始进一步学习。
1. 绑定事件
事件的绑定即我们把一个函数捆绑到一个可发生改变的控件上,例如我们为确定按钮绑定添加一个事件来验证相关信息,语法格式如下:
| 1 | Button_login.Bind(wx.EVT_BUTTON,OnclickEventName) |
wx.EVT_BUTTON是事件类型选择了按钮类型,OnclickEventName为点击按钮时执行的方法名。
我们通过这种方法来完善上一节创建的登录界面,代码如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | import wx class MyFrame(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, -1, "登录界面", size=(300, 300)) panel = wx.Panel(self)#创建一个画布,然后创建功能区并放到画布上 self.title = wx.StaticText(panel,label = '登陆界面') self.username = wx.StaticText(panel,label = '用户:') self.user_name = wx.TextCtrl(panel,style = wx.TE_LEFT) self.userpassword = wx.StaticText(panel,label = '密码:') self.user_password = wx.TextCtrl(panel,style = wx.TE_PASSWORD) self.button_login = wx.Button(panel,label = '登陆') self.button_login.Bind(wx.EVT_BUTTON,self.OnclickEventname) ...和上一节一致,在这里省略.... def OnclickEventname(self,event): ms = '' urnm = self.user_name.GetValue() pwd = self.user_password.GetValue() if urnm == '' or pwd == '': ms = '用户或密码不能为空' elif urnm == 'qy' and pwd == '123456': ms = '登陆成功' else: ms = '用户或密码错误' wx.MessageBox(ms) if __name__ == "__main__": app = wx.App() frame = MyFrame() frame.Show() app.MainLoop() |
运行图为:



我们主要对绑定的函数部分进行掌握即可,函数中的内容为获取了我们在用户和密码框中输入的内容,分三种判断方式返回三种结果,然后通过MessageBox方法把内容显示在提示框中,我们要注意在绑定的时候的代码:
| 1 | self.button_login.Bind(wx.EVT_BUTTON,self.OnclickEventname) |
事件就是通过这一行代码和下面的函数绑定在了一起,每当我们点击一次按钮,按钮就会执行函数中的内容。
wxPython(6)-下拉列表和菜单
下拉列表是由一个文本框和一个列表组成的,它有两种方法可以使用,一种是wx.ComboBox,一种是wx.Choice,前者的文本框是可变的,而后者的是固定的。
我们直接通过例子来看一下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | import wx class MyFrame(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, -1, "下拉列表", size=(300, 300)) self.Centre() panel = wx.Panel(self)#创建一个容器 box_one = wx.BoxSizer(wx.HORIZONTAL) text_one = wx.StaticText(panel,label='你喜欢的运动为:') sports = ['篮球','足球','排球'] select_one = wx.ComboBox(panel,-1,value = '足球',choices = sports,style = wx.CB_SORT) box_one.Add(text_one,1,flag=wx.LEFT|wx.RIGHT|wx.FIXED_MINSIZE,border = 7) box_one.Add(select_one,1,flag = wx.ALL|wx.FIXED_MINSIZE) box_two = wx.BoxSizer(wx.HORIZONTAL) text_two = wx.StaticText(panel,label='你喜欢的手机品牌为:') phones = ['小米','华为','苹果'] select_two = wx.Choice(panel,-1,choices = phones,style = wx.CB_SORT) box_two.Add(text_two,1,flag=wx.LEFT|wx.RIGHT|wx.FIXED_MINSIZE,border = 7) box_two.Add(select_two,1,flag = wx.ALL|wx.FIXED_MINSIZE) bbox = wx.BoxSizer(wx.VERTICAL) bbox.Add(box_one,1,flag = wx.ALL|wx.EXPAND,border = 7) bbox.Add(box_two, 1, flag=wx.ALL | wx.EXPAND, border=7) panel.SetSizer(bbox) if __name__ == "__main__": app = wx.App() frame = MyFrame() frame.Show() app.MainLoop() |
运行结果如下图:


我们可以看出两种列表的不同之处,选择使用wx.Choice的时候,选择框中的内容是固定的,只有从列表中选择,而使用wx.ComboBox的时候选择框中的内容不是固定的,关键语句:
| 1 2 | select_one = wx.ComboBox(panel, -1, value='足球', choices=sports, style=wx.CB_SORT) select_two = wx.Choice(panel, -1, choices=phones, style=wx.CB_SORT) |
2. 菜单
我们可以发现在日常生活中使用的大多图形用户界面都是有菜单项的,如下面的几张图:



点击其中一个菜单项还有多个选项供我们选择,下面我们来学习使用wxPython中的功能来实现菜单栏。
1) 创建一个菜单栏:menuBar = wx.MenuBar()。
2) 创建菜单: fileMenu = wx.Menu()
3) 创建菜单项: newItem = wx.MenuItem()
4) 添加菜单项到菜单中: fileMenu.AppendItem(newItem)
5) 添加菜单到菜单栏:menuBar.Append(fileMenu, title = "File")
6) 把菜单栏设置为界面的菜单栏:self.SetMenuBar(menuBar)
7) 绑定菜单事件:self.Bind(wx.EVT_MENT, self.menuHandler)
代码如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | import wx class MyFrame(wx.Frame): def __init__(self): super().__init__(parent=None, title="wxPython", size=(400, 300)) self.Center() self.text = wx.TextCtrl(self, -1, style=wx.TE_MULTILINE) vbox = wx.BoxSizer(wx.VERTICAL) self.SetSizer(vbox) vbox.Add(self.text, 1, flag=wx.EXPAND | wx.ALL, border=1) menubar = wx.MenuBar()#对应步骤1 self.SetMenuBar(menubar) file_menu = wx.Menu()#对应步骤2 menubar.Append(file_menu, '菜单')#对应步骤4 file_menu.Append(id=wx.ID_NEW, item='新建', helpString='new file') file_menu.AppendSeparator() edit_menu = wx.Menu() file_menu.AppendSubMenu(edit_menu, "编辑") copy_item = wx.MenuItem(edit_menu, 100, text="复制", kind=wx.ITEM_NORMAL)#对应步骤3 edit_menu.Append(copy_item) cut_item = wx.MenuItem(edit_menu, 101, text="剪切", kind=wx.ITEM_NORMAL) edit_menu.Append(cut_item) paste_item = wx.MenuItem(edit_menu, 102, text="粘贴", kind=wx.ITEM_NORMAL) edit_menu.Append(paste_item) if __name__ == "__main__": app = wx.App() frame = MyFrame() frame.Show() app.MainLoop() |
运行结果如下:

前面我们学习了两种GUI模块,下面我们串接起前面的内容来创建一个登陆+注册+写日记的图形用户界面。本节的设计思路为:首先通过一个主页面来控制登录界面(这是一种常用的设计理念,使主页面更为简洁),在登录页面控制两个页面,如果登录信息正确,那么跳转到下一个页面,若要注册也则点击进入注册页面,本节会通过四个代码,三个页面来简单实现。
1. 主页面程序(main.py)
| 1 2 3 4 5 6 | from tkinter import * from LoginPage import * root = Tk() root.title('小程序') Login(root) root.mainloop() |
2. 登陆页面程序(LoginPage.py)
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | from tkinter import * from tkinter.messagebox import * from MainPage import * from Register import * class Login(object): def __init__(self, master=None): self.root = master # 定义内部变量root self.root.minsize(300, 200) self.username = StringVar() self.password = StringVar() self.create() def create(self): self.page = Frame(self.root) # 创建Frame self.page.pack() Label(self.page).grid(row=0, stick=W) Label(self.page, text='账户: ').grid(row=1, stick=W, pady=10) Entry(self.page, textvariable=self.username).grid(row=1, column=1, stick=E) Label(self.page, text='密码: ').grid(row=2, stick=W, pady=10) Entry(self.page, textvariable=self.password, show='*').grid(row=2, column=1, stick=E) Button(self.page, text='登陆', command=self.loginCheck).grid(row=3, stick=W, pady=10) Button(self.page, text='注册', command=self.regis).grid(row=3, column=1, stick=E) def loginCheck(self): if self.username.get() == 'qy' and self.password.get() == '123456': self.page.destroy() MainPage(self.root) else: showinfo(title='错误', message='账号或密码错误!') def regis(self): self.page.destroy() app = wx.App() frame = MyFrame() frame.Show() app.MainLoop() |
3. 注册页面程序(Register.py)
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | import wx class MyFrame(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, -1, "登录界面", size=(300, 300)) panel = wx.Panel(self)#创建一个画布,然后创建功能区并放到画布上 self.title = wx.StaticText(panel,label = '注册界面') self.username = wx.StaticText(panel,label = '用户名字:') self.user_name = wx.TextCtrl(panel,style = wx.TE_LEFT) self.userpassword = wx.StaticText(panel,label = '输入密码:') self.user_password = wx.TextCtrl(panel,style = wx.TE_PASSWORD) self.userpassword1 = wx.StaticText(panel,label = '确认密码:') self.user_password1 = wx.TextCtrl(panel,style = wx.TE_PASSWORD) self.button_register = wx.Button(panel,label = '注册') container_one = wx.BoxSizer(wx.HORIZONTAL) # 创建一个box容器并控制水平排列 container_one.Add(self.username,proportion = 0,flag = wx.ALL,border = 7) container_one.Add(self.user_name,proportion = 1,flag = wx.ALL,border = 7) container_two = wx.BoxSizer(wx.HORIZONTAL) # 创建一个box容器并控制水平排列 container_two.Add(self.userpassword,proportion = 0,flag = wx.ALL,border = 7) container_two.Add(self.user_password,proportion = 1,flag = wx.ALL,border = 7) container_four = wx.BoxSizer(wx.HORIZONTAL) # 创建一个box容器并控制水平排列 container_four.Add(self.userpassword1,proportion = 0,flag = wx.ALL,border = 7) container_four.Add(self.user_password1,proportion = 1,flag = wx.ALL,border = 7) container_three = wx.BoxSizer(wx.HORIZONTAL) # 创建一个box容器并控制水平排列 container_three.Add(self.button_register,proportion =0,flag = wx.ALIGN_CENTER, border = 4) sizers = wx.BoxSizer(wx.VERTICAL) sizers.Add(self.title,proportion=0, flag=wx.BOTTOM|wx.TOP|wx.ALIGN_CENTER,border=10) sizers.Add(container_one,proportion = 0,flag =wx.EXPAND|wx.LEFT|wx.RIGHT,border=40) sizers.Add(container_two, proportion=0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=40) sizers.Add(container_four, proportion=0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=40) sizers.Add(container_three, proportion=0, flag=wx.ALIGN_CENTER|wx.TOP, border=10) panel.SetSizer(sizers) if __name__ == "__main__": app = wx.App() frame = MyFrame() frame.Show() app.MainLoop() |
4. 写日记页面程序(MainPage.py)
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | from tkinter import * class MainPage(object): def __init__(self, master=None): self.root = master # 定义内部变量root self.root.geometry('%dx%d' % (600, 400)) # 设置窗口大小 self.createPage() def createPage(self): self.inputPage = InputFrame(self.root) # 创建不同Frame self.queryPage = QueryFrame(self.root) self.countPage = CountFrame(self.root) self.aboutPage = AboutFrame(self.root) self.inputPage.pack() # 默认显示数据录入界面 menubar = Menu(self.root) menubar.add_command(label='写日记', command=self.inputData) menubar.add_command(label='看日记', command=self.queryData) self.root['menu'] = menubar # 设置菜单栏 def inputData(self): self.inputPage.pack() self.queryPage.pack_forget() self.countPage.pack_forget() self.aboutPage.pack_forget() def queryData(self): self.inputPage.pack_forget() self.queryPage.pack() self.countPage.pack_forget() self.aboutPage.pack_forget() |
5. 综合使用

输入‘qy’、密码‘123456’,点击登陆,进入下一页面。

点击注册进入下一页面:
