目录
图形用户界面(GUI)就是包含按钮、文本框等控件的窗口。Tkinter是事实上的Python标准GUI工具包,包含在Python标准安装中。当然,除此之外还有其他多个工具包。
1. 示例程序需求
我们要创建一个微型文本编辑器,需求如下:
- 让用户能够打开指定的文本文件
- 让用户能够编辑文本文件
- 让用户能够保存文件文件
- 让用户能够退出
简单布局如下:
2. 实现
2.1 初探
- 首先我们导入tkinter,为保留其命名空间,同时减少输入量,并将其重命名:import tkinter as tk
- 要创建GUI,需要创建一个将充当主窗口的顶级组件(控件):top = Tk(),此时将出现一个窗口
- 需要创建控件并放到顶级组件中,它们的名称各异。例如,要创建按钮,可实例化Button类。如果没有Tk实例,创建控件也将实例化Tk,因此可以先不实例化Tk,而直接创建控件。
- 按钮创建出来后默认是不可见的,需要使用布局管理器来告诉Tkinter将它放在什么地方。
- 控件往往包含各种属性,我们可以使用它们来修改控件的外观和行为
实现代码如下:
from tkinter import *
def clicked():
print('I am clicked!')
btn = Button()
btn.pack()
btn['text'] = 'Click me!'
btn['command'] = clicked
btn2 = Button()
btn2.pack()
btn2.config(text='Click me!', command=clicked)
# hold当前主线程
mainloop()
运行结果如下:
2.2 布局
对控件调用方法pack时,将把控件放在其父控件中。要指定主控件,可使用构造函数的第一个可选参数;如果没有执行,将把顶级主窗口用作主控件。例如:
from tkinter import *
Label(text='I am in the first window!').pack()
second = Toplevel()
Label(second, text='I am in the second window!').pack()
# hold当前主线程
mainloop()
运行结果如下:
Toplevel类表示除主窗口外的另一个顶级窗口,而Label就是文本标签。
要指定控件停靠在哪一条边上,可将参数side设置为LEFT、RIGHT、TOP或BOTTOM。要让控件在x或y方向上填满分配给它的空间,可将参数fill设置为X、Y或BOTH。要让控件随父控件一起增大,可将参数expand设置为True。
还有其他的布局管理器,具体地说是grid和place,它们可能会更能满足我们的需求。grid将控件放在不可见的表格单元格中,为此需要指定参数row和column,还可能要指定参数rowspan或columnspan——如果控件跨越多行或多列。方法place让我们能够手工放置控件,通过指定控件的x和y坐标以及高度和宽度来做到。
2.3 事件处理
除了通过设置属性command来给按钮指定动作,Tkinter还提供了更通用的事件处理机制:方法bind。示例代码如下:
from tkinter import *
top = Tk()
def callback(event):
print(event.x, event.y)
top.bind('<Button-1>', callback)
# hold当前主线程
mainloop()
运行结果为:
114 82
93 55
50 45
96 92
其中<Button-1>是使用鼠标左按钮单击的事件名称,我们将这种事件关联到函数callback。该实例中,对于鼠标单击事件,它打印出了x和y坐标。
2.4 最终的程序
最终程序的实例代码如下:
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()
运行结果如下: