wxpython应用程序对象与顶级窗口_Python:初识GUI编程【wxPython】

GUI是Graphical User Interface(图形用户界面)的缩写,在Gui中,并不是只有键入文本和返回文本,用户可以看到窗口,按钮、文本框等图形,并且可以用鼠标单机,也可以用键盘输入。GUI是与程序交换的种不同方式.GUI的程序有3个基本要素:输入,处理和输出。

一、常用的GUI框架

对于python的GUI开发,有很多工具包供我们选择。以下是一些留下的工具包。

二、安装wxPython

wxPython是一个成熟而且特性丰富的跨平台GUI工具包,使用pip 工具安装wxPython

pip install -U wxPython

使用wxPython之前,先来了解2个基础对象:应用程序对象和顶级窗口

A应用程序对象管理主事件循环,主时间循环是wxPython程序的动力,如果没有应用程序对象,wxPython应用程序将不能运行。

顶级窗口通常用于管理最重要的数据,控制并呈现给用户。这2个基础对象和应用程序的其他部分之前的关系,如图所示。

在图中,这个应用程序对象拥有顶级窗口和主循环时间。顶级窗口管理其窗口中的组件和其他分配给它的数据对象。窗口和她的组件触发的时间基于用户的动作,并接受事件通知以便于改变现实。

1、创建一个wx.App的子类

在创建应用程序之前,先来创建一个没有任何功能的子类。创建和使用一个wx.App子类,需要执行4个步骤

a:定义这个子类

b:在定义的子类中写一个OnInit()初始化方法

c:在程序的主要部分创建这个类的一个实例。

d:调用应用程序实例MainLoop()方法。这个方法将程序的控制权转交给wxPython.

创建一个没有任何功能的子类。具体代码如下:

import wx#导入wxPython

classApp(wx.App):#初始化方法

defOnInit(self):

frame= wx.Frame(parent = None,title = 'hello wyPython')#创建窗口,因为是主窗口,所以他的父类为None title:窗口标题

frame.Show()#显示窗口

return True #返回值

if __name__ == '__main__':

app= App()#创建App类实例

app.mainloop()#调用App类的MainLoop()主循环方法

上述代码中,定义了一个子类App().他冀衡父类wx.App.子类中包含一个初始方法OnInit().

在主程序中创建类的实例。然后再调用MainLoop()主循环方法。运行结果如图所示

2、直接使用wx.App

通常,如果在系统中只有一个窗口的话,可以不创建wx.App子类。直接使用wx.App.这个类提供了一个最基本的OnInit()初始化方法。具体代码如下

importwx

app=wx.App()

frame= wx.Frame(None,title = "hello world")

frame.Show()

app.MainLoop()

3、使用wx.Frame框架

在GUI中框架通常也称为窗口,框架是一个容器,用户可以将在屏幕上任意移动。并可对他进行缩放,他通常包含标题栏,菜单等。在wxPython中,wx.Frame是所有框架的父类。当你创建wx.Fame的子类时,子类应该调用其父类的构造器wx.Frame.__init__().wx.Frame构造器的语法格式如下:

wx.Frame(parent,id=1,title="“,pos = wx.DefaultPosition,size=wx.DefaultSize,style=wx.DEFAULT_FRAME_STYLE,name="frame")

参数说明:

parent:框架的父窗口。如果是顶级窗口,这个是None。

id:关于新窗口的wxPython ID号。通常设为-1,让wxPython自动生成一个新的ID.

title:窗口的标题

pos:一个wx.Point对象,他指定这个窗口的左上角在屏幕中的位置。在图形用户界面程序中。通常(0,0)是显示器的左上角。这个默认值(-1,-1)将让系统决定窗口的位置。

size:一个wx.Size对象,他指定这个窗口的初始尺寸。这个默认值(-1,-1)将让系统决定窗口的初始尺寸。

style:指定窗口类型的常量。可以使用或运算来组合他们。

name:框架内的名字。可以使用它来寻找这个窗口。

创建wx.Frame子类的代码如下:

importwxclassMyFrame(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方法

上述代码中,在主程序中调用MyFrame类,并且传递2个参数。在MyFrame类中,自动执行__init__()初始化方法。接受参数。然后调用父类wx.Frame的__init__()初始方法。设置顶级窗口的相关属性。运行结果如图所示

三、常用控件

创建完窗口以后,我们可以在窗口添加一些控件,所谓的控件,就是经常使用的按钮、文本、输入框,单选框等。

1、StaticText文本类

对于所有的UI工具来说,最基本的任务就是在屏幕上绘制纯文本,在wx.Python中,可以使用wx.StatiText类来完成。使用wx.StaticText能够改变文本的对齐方式,字体和颜色等。wx.StaticText类的构造语法如下:

wx.StaticText(parent,id,label,pos = wx.DefaultPosition,size=wx.DefaultSize,style=wx.DEFAULT_FRAME_STYLE,name="frame")

参数说明:

parent:框架的父窗口。

id:标识符。使用-1可以自动创建一个唯一的标识

label:显示在静态控件中的文本内容。

pos:一个wx.Point对象或者一个python元组。他是窗口部件的位置

size:一个wx.Size对象或者一个python元组。他是窗口部件的尺寸

style:样式标记

name:对象的名字

实例01:使用wx.StaticText输出python之禅.

importwxclassMyFrame(wx.Frame):def __init__(self,parent,id):

wx.Frame.__init__(self,parent,id,title='创建StaticText类',

pos= (100,100),size = (600,400))

panel= wx.Panel(self) #创建画板

#创建标题,并设置字体

title = wx.StaticText(panel,label="Python之禅",pos = (100,20))

font= wx.Font(16,wx.DEFAULT,wx.FONTSTYLE_NORMAL,wx.NORMAL)

title.SetFont(font)#创建文本

wx.StaticText(panel,label = "优美胜于丑陋",pos = (50,50))

wx.StaticText(panel,label="明了胜于晦涩", pos = (50, 70))

wx.StaticText(panel, label="简洁胜于复杂", pos=(50, 90))

wx.StaticText(panel, label="复杂胜于凌乱", pos=(50, 110))

wx.StaticText(panel, label="扁平胜于嵌套", pos=(50, 130))

wx.StaticText(panel,label="间隔胜于紧凑", pos = (50, 150))

wx.StaticText(panel, label="可读性很重要", pos=(50, 170))

wx.StaticText(panel, label="即便假借特例的实用性之名,也不可违背这些规则", pos=(50, 190))

wx.StaticText(panel, label="不要包容所有错误,除非你确定需要这样做", pos=(50, 210))

wx.StaticText(panel, label="当存在多种可能,不要尝试去猜测", pos=(50, 230))

wx.StaticText(panel, label="尽量找一种,最好是唯一一种明显的解决方案", pos=(50, 250))

wx.StaticText(panel, label="虽然这并不容易,因为你不是 Python 之父", pos=(50, 270))

wx.StaticText(panel, label="做也许好过不做,但不假思索就动手还不如不做", pos=(50, 290))

wx.StaticText(panel, label="如果你无法向人描述你的方案,那肯定不是一个好方案;反之亦然", pos=(50, 310))

wx.StaticText(panel, label="命名空间是一种绝妙的理念,我们应当多加利用", pos=(50, 330))if __name__ == "__main__":

app=wx.App()

frame= MyFrame(parent=None,id = -1)

frame.Show()

app.MainLoop()

上述代码中,使用panel = wx.Panel(self)来创建画板,并将panel作为父类,然后将组建放入窗体中,此外,使用wx.Font类来设置字体创建一个字体实例,需要使用如下的构造函数:

wx.Font(pointSize,family,style,weight,underline=False,faceName="",encoding = wx.FONTENCODING_DEFFAULT)

pointSize:字体的整数尺寸,单位为磅。

family:用于快速指定一个字体而不需要知道实际字体的名字。

style:指字体是否倾斜。

weight:指字体的醒目程度。

underline:在windows系统下生效,如果取值为true,则是加下划线,False则无下划线。

faceName:指定字体名。

encoding= 允许在几个编码中选择一个,大多数情况可以使用默认编码。

运行结果如图

2 、TextCtrl输入文本类

wx.StaticText类智能够用于显示纯粹的静态文本,但是有时候要输入文本与用户进行交互,此时就需要使用wx.TextCtrl类,它允许输入单行和多行文本,他可以做为密码输入控件。

wx.TextCtrl类的构造函数语法格式如下:

wx.TextCtrl(parent,id,value = " ",pos = wx.DefaulPosition,size = wx.DefaultSize,style= 0,validator =wx.DefaultValidator name =wx.textCtrlNameStr)

参数说明:

style:单行wxTextCtrl样式,取值说明如下:

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:控件中的文本左右对齐。

value:显示该控件中的初始文本。

validator:常用于过滤数据以确保只能键入要接受的数据。

实例2,使用一个wx.TextCtrl类和wx.StaticText类实现一个包含用户名和密码的登录界面。

importwxclassMyFrame(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_pwd= wx.StaticText(panel,pos = (50,90),label= "密 码")

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)

frame.Show()

app.MainLoop()

上述代码中,使用wx.TextCtrl类生成用户名,并且设置控件中的文本左对齐。使用wx.TextCtrl类,生成密码。并且设置文本用型号代替。执行效果如图

3、Button按钮类

按钮是GUI界面应用最为广泛的控件,他常用语捕获用户生成的单机时间,最明显的用途是触发绑定到一个处理函数,wxPython类库提供不同类型的按钮,其中最常用的是wx.Button类。

实例3,在实例2的基础上加上【确认】和【取消】按钮

importwxclassMyFrame(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_pwd= wx.StaticText(panel,pos = (50,90),label= "密 码")

self.text_password= wx.TextCtrl(panel,pos = (100,90),size = (235,25),style =wx.TE_PASSWORD)

self.bt_confirm= wx.Button(panel,label="确定",pos=(105,130))

self.bt_cancel= wx.Button(panel,label = "取消",pos = (195,130))if __name__== "__main__":

app=wx.App()

frame= MyFrame(parent=None, id=-1)

frame.Show()

app.MainLoop()

Button

四、BoxSizer布局

在前面的实例中,使用了文本和按钮等空间并将这些空间通过pos参数布置在pannel面板上。虽然这种设置坐标的方式很容易理解,但是过程很麻烦,此外空间的几核位置是绝对位置,也就是固定道德。当调整窗口大小时,界面会不美观。在wxPython中有一种更智能的布局方式-sizer(尺寸器)。sizer是用户自动布局一组窗口空间的算法。sizer被附加到一个容器,通常是一个框架或者面板。在父容器中,创建的子窗口空间必须被分别添加到sizer。当sizer被附加到容器时,它随后就可以管理它所包含的子布局。

wxPython提供了5个sizer.

(1)使用BoxSizer布局

从尺寸器会管理组件的尺寸。只要将部件添加到尺寸器上,再添加一些布局参数,就可以让尺寸器自己去管理父组件的尺寸。下面使用BoxSize实现简单的布局。代码如下:

importwxclassMyFrame(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)

vsizer.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)

frame.Show()

app.MainLoop()

执行结果如图

上述代码中,首先设置了增加背景控件(wx.Panel),并创建了一个wx.BoxSizer,它带一个决定其水平还是垂直的参数(wx.HORIZONTAL或者wxVERTICAL),默认为水平;然后用Add方法将孔家加入到sizer;最后使用面板SetSizer()方法设定他的尺寸器。

Add()方法的语法格式如下;

Box.add(control,proportion,flag,border)

参数说明:

control:要添加的控件。

proportion:所添加控件在定义的方式所代表方向向上占据的空间比例。如果有如3个按钮,他们的比例值分别为0,1,2,他们都已经天追到一个宽度为30的水平排列wx.BoxSizer,起始宽度都是10,当sizer的宽度从30变成60时,按钮1的宽度保持不变,任然是10,按钮2的苦读约为(10+(60-30)*1/(1+2))=30,按钮2约为20.

flag:flag参数与border参数结合使用可以指定边距宽度,包括以下选项:

wx.LEFT:左边距

wx.RIGHT:右边距

wx.BOTTOM:底边距

wx.TOP:上边距

wx.ALL:上下左右4个边距

可以通过竖线“|”操作符,来联合使用这些标志,此flag参数还可以与proportion是参数结合,指定控件本身的对齐(排列)方式,包括以下选项:

wx.ALIGN_LEFT:左边对齐

wx.ALIGN_RIGHT:右边对齐

wx.ALIGN_TOP:顶部对齐

wx.ALLGN_BOTTOM:底边对齐

wx.ALGN_CENTER_VERTICAL:处置对齐

wx.ALIGN_CENTER_HORIZONTAL:水平对齐

wx.ALIGN_CENTER:居中对齐

wx.EXPAND:所添加控件将占有sizer定位方向上所有可用的控件

boder:控制所添加控件的边距,就是在部件之间添加一些像素的空白。

实例4,使用BoxSizer布局方式,实现实例3道德界面布局效果。具体代码如下:

#导入wxPython

importwxclassMyFrame(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="请输入用户名和密码")#设置控件名称

self.label_user = wx.StaticText(panel, label="用户名:")

self.text_user= wx.TextCtrl(panel, style=wx.TE_LEFT)#输入框

self.label_pwd = wx.StaticText(panel, label="密 码:")

self.text_password= wx.TextCtrl(panel, style=wx.TE_PASSWORD)#输入框

#创建“确定”,“取消”按钮并 绑定事件

self.bt_confirm = wx.Button(panel, label="确定")

self.bt_canel= wx.Button(panel, label="取消")#创建布局 添加容器,容器中控件横向排列

hsizer_user =wx.BoxSizer(wx.HORIZONTAL)

hsizer_user.Add(self.label_user, proportion=0, flag=wx.ALL, border=5)#文本的[用户名占比]

hsizer_user.Add(self.text_user, proportion=1, flag=wx.ALL, border=5)#[用户名输入框占比]

#因为是用户名和用户名的输入框是在一行,所以设置用1个容器来设置,以下都一样

hsizer_pwd =wx.BoxSizer(wx.HORIZONTAL)

hsizer_pwd.Add(self.label_pwd, proportion=0, flag=wx.ALL, border=5)#文本的[密码占比]

hsizer_pwd.Add(self.text_password, proportion=1, flag=wx.ALL, border=5)#[密码输入框占比]

hsizer_button =wx.BoxSizer(wx.HORIZONTAL)

hsizer_button.Add(self.bt_confirm, proportion=0, flag=wx.ALIGN_CENTRE, border=5)#按钮确认占比

hsizer_button.Add(self.bt_canel, proportion=0, flag=wx.ALIGN_CENTRE, border=5)#按钮取消占比

#添加容器,容器中的控件纵向排列

vsizer_all =wx.BoxSizer(wx.VERTICAL)

vsizer_all.Add(self.title, proportion=0, flag=wx.BOTTOM | wx.TOP | wx.ALIGN_CENTRE, border=15)#title是单独的,所以在横向没设置容器

vsizer_all.Add(hsizer_user, proportion=0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=45)

vsizer_all.Add(hsizer_pwd, proportion=0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=45)

vsizer_all.Add(hsizer_button, proportion=0, flag=wx.ALIGN_CENTRE | wx.TOP | wx.RIGHT, border=15)

panel.SetSizer(vsizer_all)#备注因为是竖向排列只有1个容器,横向的话有3个容器

if __name__ == "__main__":

app=wx.App()

frame= MyFrame(parent=None, id=-1)

frame.Show()

app.MainLoop()

在上述代码中,首先创建按钮和文本控件,然后将其添加到容器中,并且设置横向排列接着设置纵向排列。在蒲剧过程中,通过设置控件的flag和border参数,实现控件位置间的布局。运行结果和实例3的类似。

五、绑定事件

当发生一个事件时,需要让程序注意这些事件并作出反应。这时可以将函数绑定到所涉及事件可能的控件上,当事件发生时,函数就会被调用利用控件Bind()方法将事件处理处理函数绑定到给定的事件上。例如为【确定】按钮加一个单机事件,代码如下。

bt_confirm.Bind(wx.EVT_BUTTON,OnclickSubmit)

参数说明:

wx.EVT_BUTTON:事件类型为按钮箱,在wxPython中有很多wx.EVT_开头的事件类型,例如,类型wx.EVT_MOTION产生移动鼠标,类型wx.ENTER_WINDOW和wx.LEAVE_WINDOW产生当鼠标进入或者离开一个窗口空间,类型wx.EVT_MOUSEWHEEL被绑定到鼠标滚轮的活动

OnclickSunbmit:方法名,事件发生立即执行的方法。

实例5,在实例4的基础上,分别为“确定”,“取消”按钮添加单机事件当用户输入用户名密码后,单机“确定”按钮,如果输入的用户名为“sjc”且密码为“xfd”.则弹出对话框提示“登陆成功”,否则提供“用户名密码不匹配”。当用户单机“取消”按钮时,清空用户输入的用户名密码。

#导入wxPython

importwxclassMyFrame(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="请输入用户名和密码")#设置控件名称

self.label_user = wx.StaticText(panel, label="用户名:")

self.text_user= wx.TextCtrl(panel, style=wx.TE_LEFT)#输入框

self.label_pwd = wx.StaticText(panel, label="密 码:")

self.text_password= wx.TextCtrl(panel, style=wx.TE_PASSWORD)#输入框

#创建“确定”,“取消”按钮并 绑定事件

self.bt_confirm = wx.Button(panel, label="确定")

self.bt_confirm.Bind(wx.EVT_BUTTON,self.OnclickSunbmit)

self.bt_canel= wx.Button(panel, label="取消")

self.bt_canel.Bind(wx.EVT_BUTTON, self.OnclickCancel)#创建布局 添加容器,容器中控件横向排列

hsizer_user =wx.BoxSizer(wx.HORIZONTAL)

hsizer_user.Add(self.label_user, proportion=0, flag=wx.ALL, border=5)#文本的[用户名占比]

hsizer_user.Add(self.text_user, proportion=1, flag=wx.ALL, border=5)#[用户名输入框占比]

#因为是用户名和用户名的输入框是在一行,所以设置用1个容器来设置,以下都一样

hsizer_pwd =wx.BoxSizer(wx.HORIZONTAL)

hsizer_pwd.Add(self.label_pwd, proportion=0, flag=wx.ALL, border=5)#文本的[密码占比]

hsizer_pwd.Add(self.text_password, proportion=1, flag=wx.ALL, border=5)#[密码输入框占比]

hsizer_button =wx.BoxSizer(wx.HORIZONTAL)

hsizer_button.Add(self.bt_confirm, proportion=0, flag=wx.ALIGN_CENTRE, border=5)#按钮确认占比

hsizer_button.Add(self.bt_canel, proportion=0, flag=wx.ALIGN_CENTRE, border=5)#按钮取消占比

#添加容器,容器中的控件纵向排列

vsizer_all =wx.BoxSizer(wx.VERTICAL)

vsizer_all.Add(self.title, proportion=0, flag=wx.BOTTOM | wx.TOP | wx.ALIGN_CENTRE, border=15)#title是单独的,所以在横向没设置容器

vsizer_all.Add(hsizer_user, proportion=0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=45)

vsizer_all.Add(hsizer_pwd, proportion=0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=45)

vsizer_all.Add(hsizer_button, proportion=0, flag=wx.ALIGN_CENTRE | wx.TOP | wx.RIGHT, border=15)

panel.SetSizer(vsizer_all)#备注因为是竖向排列只有1个容器,横向的话有3个容器

defOnclickSunbmit(self, event):

message= ""username=self.text_user.GetValue()

password=self.text_password.GetValue()if username == "" or password == "":

message= "用户名密码不能为空"

elif username == "sjc" and password == "xfd":

message= "登陆成功"

else:

message= "用户名密码不匹配"wx.MessageBox(message)defOnclickCancel(self,event):

self.text_user.SetValue("")#清空用户名

self.text_password.SetValue("")#清空密码

if __name__ == "__main__":

app=wx.App()

frame= MyFrame(parent=None, id=-1)

frame.Show()

app.MainLoop()

事件

在商户代码中,分别使用bind()函数为bt.confirm和bt_cancel绑定了单机事件。运行结果如图所示

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值