Python进阶第一课--图形用户界面

1.前言

    从本节开始,我们将会介绍一些Python里面比较有趣而且常用的功能。首先的就是Python程序的图形化用户界面,也就是那些带有按钮的文本框的窗口等等。在编写Python GUI程序以前你首先要确定使用哪个GUI平台。支持Python的流行的GUI工具包有很多。常见的有:Tkinkter、wxpython、PythonWin、Java Swing、PyGTK、PyQt。我们在这里使用的是wxpython,很方便安装和使用的GUI工具,大家可以自行去官网下载安装。

2.开始

2.1窗口和组件

    窗口也称为框架(Frame),它是wx.Frame的实例。wx框架中的部件是由它们的父部件使用构造函数的第一个参数创建的。如果你需要创建一个单独地窗口,就不需要考虑父部件,使用None就可以。来看看这个的具体用法:

import wx
app=wx.App()
win=wx.Frame(None)
win.Show()
app.MainLoop()

运行结果如下所示:


    在上面的例子中可以看到,wx包中的方法都是以大写字母开头的,而这和Python的习惯是相反的。这样做的原因是:这些方法名和基础的C++包wxWidgets中的方法名都是对应的。尽管没有正式的规则反对方法或者函数名以大写开头,但是规范的做法是保留这样名字。接着,我们就要在框架上添加按钮,添加按钮的方法也很简单:

import wx
app=wx.App()
win=wx.Frame(None)
btn=wx.Button(win)
win.Show()
app.MainLoop()

运行结果如下所示:

对比上面的运行结果,我们会得到一个带有按钮的窗口。当然这样做的还是不够的,窗口没有标题,按钮没有标签说明,而且我们希望按钮的布局更加合理。

2.2标签、标题和位置

    为了让我们设计的框架内容更加丰富、看起来更加完美。可以在创建部件的时候使用构造函数的label参数设定它们的标签。同样的,也可以用title参数设定框架的标题。最好用的方法就是为wx构造函数使用关键字参数。来看看:

import wx
app=wx.App()
win=wx.Frame(None,title="Simple Editor")
loadButton=wx.Button(win, label='Open')
saveButton=wx.Button(win,label='Save')
win.Show()
app.MainLoop()

看看运行结果:

嗯?我可以创建了两个button啊,怎么另一个不见了。丢了?其实是隐藏了,在这里我们不能只顾创建组件,还要适当注意组件的布局,合理地将你所创建的开关显示出来。一个方法是利用pos参数和size参数在构造函数内设置位置和尺寸。

import wx
app=wx.App()
win=wx.Frame(None,title="Simple Editor",size=(410,335))
win.Show()
loadButton=wx.Button(win, label='Open',pos=(225,5),size=(80,25))
saveButton=wx.Button(win,label='Save',pos=(315,5),size=(80,25))
filename=wx.TextCtrl(win,pos=(5,5),size=(210,25))
contents=wx.TextCtrl(win,pos=(5,35),size=(390,260),style=wx.TE_MULTILINE | wx.HSCROLL)
app.MainLoop()

看看运行结果:

是不是显示出来了,而且好看了很多。

在上面的代码中,我们创建了两个文本控件(textcontrol,wx.TextCtrl对象),每个都采用了自定义的风格。默认的文本控件是文本框,就是一行可编辑的文本,没有滚动条,为了创建文本区只要采用style参数调整风格便可。style参数实际上是个整数,但不可以直接指定,可以使用按位或运算符OR或者管道运算符联合wx模块中具有特殊名字的风格来指定。这里,我们联合了wx.TE_MULTIINE来获得多行文本区(默认有垂直滚动条)以及wx.HSCROLL来获得水平滚动条。

2.3尺寸器

    在前面设置布局的时候我们都是采用显式的参数,每个组件的位置和大小都是显式设置的,但是没有确定在窗口大小变化的时候它们的行为是什么。指定行为的方法有很多,在wx内进行布局最简单方法是使用尺寸器(sizer),最容易使用的工具就是wx.BoxSizer。

    尺寸器会管理组件的尺寸,只要将部件添加到尺寸器上,再加上一些布局参数,然后让尺寸器自己去管理父组件的尺寸。来看看具体的例子:

import wx
app=wx.App()


win=wx.Frame(None,title="Simple Editor", size=(410,335))

bkg=wx.Panel(win)


loadButton=wx.Button(bkg, label='Open')
loadButton.Bind(wx.EVT_BUTTON,load)

saveButton=wx.Button(bkg,label='Save')
saveButton.Bind(wx.EVT_BUTTON,save)

filename=wx.TextCtrl(bkg)
contents=wx.TextCtrl(bkg,style=wx.TE_MULTILINE | wx.HSCROLL)

hbox=wx.BoxSizer()
hbox.Add(filename,proportion=1,flag=wx.EXPAND)
hbox.Add(loadButton,proportion=0,flag=wx.LEFT,border=5)
hbox.Add(saveButton,proportion=0,flag=wx.LEFT,border=5)

vbox=wx.BoxSizer(wx.VERTICAL)
vbox.Add(hbox,proportion=0,flag=wx.EXPAND | wx.ALL ,border=5)
vbox.Add(contents,proportion=1,flag=wx.EXPAND | wx.LEFT | wx.BOTTOM | wx.RIGHT, border=5)

bkg.SetSizer(vbox)
win.Show()

app.MainLoop()

    这段代码的运行结果和前列相同,但是使用了相对坐标而不是绝对坐标。

    wx.BoxSizer的构造函数带有一个决定它是水平还是垂直的参数(wx.HORIZONTAL或者wx.VERTICAL),默认为水平。Add方法有几个参数,proportion参数根据在窗口改变大小时所分配的空间设置比例。flag参数类似于构造函数中的style参数,可以使用按位或运算符连接构造符号常量对其进行构造。wx.EXPAND标记确保组件会扩展到所分配的空间中。而wx.LEFT,wx.RIGHT,wx.TOP,wx.BOTTOM和wx.ALL标记决定边框参数应用于哪个边,边框参数用于设置边缘宽度。

2.4事件处理

    在GUI中,用户执行的动作叫做事件。可以将事件绑定到所涉及的时间可能发生的组件上达到这个效果。当事件发生时,函数会被调用。利用部件的Bind方法可以将事件处理函数链接到给定的事件上。

    假设写了一个负责打开文件的函数,并将其命名为load。然后就可以像下面这样将该函数作为loadButton的事件处理函数:

    loadButton.Bind(wx.EVT_BUTTON,load)

点击按钮的时候,函数被调用。名为wx.EVT_BUTTON的符号常量表示一个按钮事件,wx对于各种事件都有这样的事件常量。

最后,我们来看一下最终完成的程序:

import wx

def load(event):
    file=open(filename.GetValue())
    contents.SetValue(file.read())
    file.close()

def save(event):
    file=open(filename.GetValue(), 'w')
    file.write(contents.GetValue())
    file.close()

app=wx.App()


win=wx.Frame(None,title="Simple Editor", size=(410,335))

bkg=wx.Panel(win)


loadButton=wx.Button(bkg, label='Open')
loadButton.Bind(wx.EVT_BUTTON,load)

saveButton=wx.Button(bkg,label='Save')
saveButton.Bind(wx.EVT_BUTTON,save)

filename=wx.TextCtrl(bkg)
contents=wx.TextCtrl(bkg,style=wx.TE_MULTILINE | wx.HSCROLL)

hbox=wx.BoxSizer()
hbox.Add(filename,proportion=1,flag=wx.EXPAND)
hbox.Add(loadButton,proportion=0,flag=wx.LEFT,border=5)
hbox.Add(saveButton,proportion=0,flag=wx.LEFT,border=5)

vbox=wx.BoxSizer(wx.VERTICAL)
vbox.Add(hbox,proportion=0,flag=wx.EXPAND | wx.ALL ,border=5)
vbox.Add(contents,proportion=1,flag=wx.EXPAND | wx.LEFT | wx.BOTTOM | wx.RIGHT, border=5)

bkg.SetSizer(vbox)
win.Show()

app.MainLoop()

    和上面的相比,加入了load和save函数。大家可以自己试试这段代码的功能到底是什么。

这就是代码的运行结果,自己动手实践,你就知道会是什么结果。

好了,这部分内容就先说到这里,一定要练习!!!


猜你喜欢

转载自blog.csdn.net/qq_34454366/article/details/80734031