第十二章 图形用户界面
GUI
就是包含按钮、文本框等控件的窗口
Tkinter
是事实上的Python标准GUI工具包
创建GUI示例应用程序
初探
导入tkinter
import tkinter as tk
也可导入这个模块的所有内容
from tkinter import *
要创建GUI,可创建一个将充当主窗口的顶级组件(控件)。
为此,可实例化一个Tk对象。
top = Tk()
调用函数mainloop
以进入Tkinter主事件循环,而不是直接退出程序。
from tkinter import *
top = Tk()
mainloop()
效果图如下:
创建按钮,可实例化Button类。
需要使用布局管理器(也叫几何体管理器)来显示按钮的位置(使用管理器pack
)
按钮也可以指定一些文本、给按钮添加行为
from tkinter import *
button = Button()
button.pack()
button['text'] = 'Click me!'
def clicked():print("I was clicked!")mainloop()
效果图如下:
可以不分别给属性赋值,而使用方法config同时设置多个属性。
button.config(text='Click me!',command=clicked)
还可使用控件的构造函数来配置控件。
Button(text='click me too!',command=clicked).pack()
布局
对控件调用方法pack时,将把控件放在其父控件(主控件)中。
from tkinter import *
Label(text="I'm in the first window!").pack()
second = Toplevel()
Label(second,text="I'm in the second window!").pack()
效果图如下:
Toplevel类表示除主窗口外的另一个顶级窗口,而Label就是文本标签。
一列按钮
from tkinter import *
for i in range(10):Button(text=i).pack()mainloop()
效果图如下:
要快速了解可用的选项,可执行如下命令
help(Pack.config)
'''
Help on function pack_configure in module tkinter:pack_configure(self, cnf={}, **kw)Pack a widget in the parent widget. Use as options:after=widget - pack it after you have packed widgetanchor=NSEW (or subset) - position widget according togiven directionbefore=widget - pack it before you will pack widgetexpand=bool - expand widget if parent size growsfill=NONE or X or Y or BOTH - fill widget if widget growsin=master - use master to contain this widgetin_=master - see 'in' option descriptionipadx=amount - add internal padding in x directionipady=amount - add internal padding in y directionpadx=amount - add padding in x directionpady=amount - add padding in y directionside=TOP or BOTTOM or LEFT or RIGHT - where to add this widget.
'''
还有其他的布局管理器,具体地说是grid和place
help(Grid.configure)
'''
Help on function grid_configure in module tkinter:grid_configure(self, cnf={}, **kw)Position a widget in the parent widget in a grid. Use as options:column=number - use cell identified with given column (starting with 0)columnspan=number - this widget will span several columnsin=master - use master to contain this widgetin_=master - see 'in' option descriptionipadx=amount - add internal padding in x directionipady=amount - add internal padding in y directionpadx=amount - add padding in x directionpady=amount - add padding in y directionrow=number - use cell identified with given row (starting with 0)rowspan=number - this widget will span several rowssticky=NSEW - if cell is larger on which sides will thiswidget stick to the cell boundary
'''
help(Place.config)
'''
Help on function place_configure in module tkinter:place_configure(self, cnf={}, **kw)Place a widget in the parent widget. Use as options:in=master - master relative to which the widget is placedin_=master - see 'in' option descriptionx=amount - locate anchor of this widget at position x of mastery=amount - locate anchor of this widget at position y of masterrelx=amount - locate anchor of this widget between 0.0 and 1.0relative to width of master (1.0 is right edge)rely=amount - locate anchor of this widget between 0.0 and 1.0relative to height of master (1.0 is bottom edge)anchor=NSEW (or subset) - position anchor according to given directionwidth=amount - width of this widget in pixelheight=amount - height of this widget in pixelrelwidth=amount - width of this widget between 0.0 and 1.0relative to width of master (1.0 is the same widthas the master)relheight=amount - height of this widget between 0.0 and 1.0relative to height of master (1.0 is the sameheight as the master)bordermode="inside" or "outside" - whether to take border width ofmaster widget into account
'''
事件处理
通过设置属性command
给按钮指定动作(action),这是一种特殊的事件处理。
Tkinter还提供了更通用的事件处理机制:方法bind
。要让控件对特定的事件进行处理,可对其调用方法bind,并指定事件的名称和要使用的函数。
点哪儿显示所点击的坐标位置(鼠标单击事件,提供x和y坐标)
其中是使用鼠标左按钮(按钮1)单击的事件名称。
将这种事件关联到函数callback。
这样,每当用户在窗口top中单击时,都将调用这个函数。向函数callback传递一个event对象,这个对象包含的属性随事件类型而异。
from tkinter import *
top = Tk()
def callback(event):print(event.x,event.y)top.bind('<Button-1>',callback)#结果为:'2435082162376callback'
mainloop()
效果图如下:
当然也可以查询帮助
help(Tk.bind)
'''
Help on function bind in module tkinter:bind(self, sequence=None, func=None, add=None)Bind to this widget at event SEQUENCE a call to function FUNC.SEQUENCE is a string of concatenated eventpatterns. An event pattern is of the form<MODIFIER-MODIFIER-TYPE-DETAIL> where MODIFIER is oneof Control, Mod2, M2, Shift, Mod3, M3, Lock, Mod4, M4,Button1, B1, Mod5, M5 Button2, B2, Meta, M, Button3,B3, Alt, Button4, B4, Double, Button5, B5 Triple,Mod1, M1. TYPE is one of Activate, Enter, Map,ButtonPress, Button, Expose, Motion, ButtonReleaseFocusIn, MouseWheel, Circulate, FocusOut, Property,Colormap, Gravity Reparent, Configure, KeyPress, Key,Unmap, Deactivate, KeyRelease Visibility, Destroy,Leave and DETAIL is the button number for ButtonPress,ButtonRelease and DETAIL is the Keysym for KeyPress andKeyRelease. Examples are<Control-Button-1> for pressing Control and mouse button 1 or<Alt-A> for pressing A and the Alt key (KeyPress can be omitted).An event pattern can also be a virtual event of the form<<AString>> where AString can be arbitrary. Thisevent can be generated by event_generate.If events are concatenated they must appear shortlyafter each other.FUNC will be called if the event sequence occurs with aninstance of Event as argument. If the return value of FUNC is"break" no further bound function is invoked.An additional boolean parameter ADD specifies whether FUNC willbe called additionally to the other bound function or whetherit will replace the previous function.Bind will return an identifier to allow deletion of the bound function withunbind without memory leak.If FUNC or SEQUENCE is omitted the bound function or listof bound events are returned.
'''
最终的程序
简单的GUI文本编辑器
1,需要输入所要编辑的文本地址
2,点击Open,即可打开该文本文件
3,在下方编辑栏中可随意编辑
4,点击Save即可保存
from tkinter import *
from tkinter.scrolledtext import ScrolledText
def load():with open(filename.get()) as file:contents.delete('1.0', END)contents.insert(INSERT, file.read())def save():with open(filename.get(), 'w') as file:file.write(contents.get('1.0', END))top = Tk()
top.title("Simple Editor")contents = ScrolledText()
contents.pack(side=BOTTOM, expand=True, fill=BOTH)filename = Entry()
filename.pack(side=LEFT, expand=True, fill=X)Button(text='Open', command=load).pack(side=LEFT)
Button(text='Save', command=save).pack(side=LEFT)mainloop()
效果图如下:
小结
概念 | 描述 |
---|---|
图形用户界面(GUI) | GUI有助于让应用程序对用户更友好。并非所有的程序都需要GUI,但只要程序需要与用户交互,GUI就可能很有帮助。 |
Tkinter | Tkinter是一个跨平台的Python GUI工具包,成熟而且使用广泛。 |
布局 | 通过指定组件的几何属性,很容易对其进行定位,但要确保它们在父窗口的大小发生变化时做出正确的反应,就必须使用布局管理器。 |
事件处理 | GUI工具包中用户触发事件执行的操作。要发挥作用,程序可能需要响应某些事件,否则用户将无法与之交互。在Tkinter中,要给组件添加事件处理程序,可使用方法bind。 |