
假期快乐| - 1 - GUI的终极选择:Tkinter TK + interface
先举一个例子: import tkinter as tk#创建一个主窗口用于容纳整个GUI程序 app = tk.Tk() #设置主窗口对象的标题栏 app.title('hello world')#添加一个Label组件,Label组件可以显示为本、图标或者图片 theLabel = tk.Label(app, text='我的第一个窗口程序!') #调用Label的pack()方法自动调节组件自身尺寸 theLabel.pack()#显示窗口 app.mainloop() 进阶版本:把GUI封装成类
import tkinter as tkclass APP:
def __init__(self, master):
frame = tk.Frame(master)
#LEFT设置左对齐,RIGHT设置右对齐,BUTTON
frame.pack(side = tk.LEFT, padx = 10, pady = 10) #黑色背景白色字体,bg为背景
self.hi_there = tk.Button(frame, text='打招呼', fg='white', bg='black', command = self.say_hi)
self.hi_there.pack() def say_hi(self):
print('大家好')root = tk.Tk()
app = APP(root)root.mainloop()
- 2 -
Label组件、Button组件
Label组件:
tkinter import *root = Tk()textLabel = Label(root, text='有风险,请确认后点击')
textLabel.pack()photo = PhotoImage(file='18.gif')
imgLabel = Label(root, image=photo)
imgLabel.pack()mainloop()将图片和文字分开,例如作为背景from tkinter import *root = Tk()photo = PhotoImage(file=r"image/bg.gif")
theLabel = Label(root,
text="学Python\n真掉发",
justify=LEFT,
image=photo,
compound=CENTER, # 设置文本和图像的混合模式
font=("华康少女字体", 20), # 设置字体和字号
fg="white" # 设置文本颜色
)
theLabel.pack()mainloop()
Button组件:Button组件用于实现一个按钮,它的绝大多数选项与Label组件是一 样的。不过Button组件有一个Label组件实现不了的功能,那就是可以接 收用户的信息。
from tkinter import *
# 导入tkinter模块的所有内容def callback():
var.set("吹吧你,我才不信呢~")root = Toplevel()frame1 = Frame(root)
frame2 = Frame(root)# 创建一个文本Label对象
var = StringVar()
var.set("您所下载的影片含有未成年人限制内容,\n请满18岁后再点击观看!")
textLabel = Label(frame1,
textvariable=var,
justify=LEFT)
textLabel.pack(side=LEFT)# 创建一个图像Label对象
# 用PhotoImage实例化一个图片对象(支持gif格式的图片)
photo = PhotoImage(file=r"18.gif")
imgLabel = Label(frame1, image=photo)
imgLabel.pack(side=RIGHT)# 加一个按钮
theButton = Button(frame2, text="已满18周岁", command=callback)
theButton.pack()frame1.pack(padx=10, pady=10)
frame2.pack(padx=10, pady=10)mainloop()
- 3 -
Checkbutton、Radiobutton、LabelFrame、Entry
Checkbutton组件:就是常见的多选按钮,而Radiobutton则是单选按钮。
from tkinter import *
root = Tk()
#需要一个Tkinter变量,表示该按钮是否被选中
v = IntVar()
c = Checkbutton(root, text='测试一下', variable = v)
c.pack()
#如果选项选中,则变量v被赋值为1,否则为0,这里用一个Label标签动态展示
l = Label(root, textvariable = v)
l.packmainloop()
翻牌子程序
from tkinter import*
root = Tk()
Girls = ['西施','貂蝉','王昭君','杨玉环']
v = []
for girl in Girls:
v.append(IntVar())
b = Checkbutton(root,text = girl,variable =[-1])
#要左对齐,也就是设置b.pack(anchor=W),anchor选项用于指定显示位置,可以设置为N、NE、E、SE、S、 SW、W、NW和CENTER九个不同的值。
b.pack(anchor=W)mainloop()
Radiobutton组件
Radiobutton组件与Checkbutton组件的用法基本一致,唯一不同的是 Radiobutton实现的是“单选”的效果。 要实现这种互斥的效果,同一组内的所有Radiobutton只能共享一个 variable选项,并且需要设置不同的value选项值:
from tkinter import *root = Tk()v = IntVar()Radiobutton(root, text="One", variable=v, value=1).pack(anchor=W)
Radiobutton(root, text="Two", variable=v, value=2).pack(anchor=W)
Radiobutton(root, text="Three", variable=v, value=3).pack(anchor=W)mainloop()如果有多个选项,可以使用循环来处理,这样会使得代码更加简洁:from tkinter import *root = Tk()LANGS = [
("Python", 1),
("Perl", 2),
("Ruby", 3),
("Lua", 4)]v = IntVar()
v.set(1)for lang, num in LANGS:
b = Radiobutton(root, text=lang, variable=v, value=num)
#设置方框选中,添加参数indicatoron=False
b.pack(anchor=W)
#设置横向填充:b.pack(fill=x)竖向为y
mainloop()
LabelFrame组件
LabelFrame组件是Frame框架的进化版,从样式上来看,也就是添加Label的Frame,但有了它,Checkbutton和Radiobutton的组件分组就 变得简单了:
from tkinter import *root = Tk()group = LabelFrame(root, text="最好的脚本语言是?", padx=5, pady=5)
group.pack(padx=10, pady=10)LANGS = [
("Python", 1),
("Perl", 2),
("Ruby", 3),
("Lua", 4)]v = IntVar()
v.set(1)
for lang, num in LANGS:
b = Radiobutton(group, text=lang, variable=v, value=num)
b.pack(anchor=W)mainloop()
Entry组件:输入框
from tkinter import*
root = Tk()
e = Entry(root)
e.pack(padx=20,pady=20)#间距
e.delete(0, END)
e.insert(0,'默认文本...')
mainloop()
程序实现
from tkinter import *
root = Tk()
# Tkinter总共提供了三种布局组件的方法:pack(),gird()和place()
# grid()方法允许你用表格的形式来管理组件的位置
# row选项代表行,column选项代表列
# 例如 row=1,column=2 表示第二行第三列(0表示第一行)
Label(root, text="作品:").grid(row=0)
Label(root, text="作者:").grid(row=1)
e1 = Entry(root)
e2 = Entry(root)
e1.grid(row=0, column=1, padx=10, pady=5)
e2.grid(row=1, column=1, padx=10, pady=5)
def show():
print("作品:《%s》" % e1.get())
print("作者:%s" % e2.get())
e1.delete(0, END)
e2.delete(0, END)
# 如果表格大于组件,那么可以使用sticky选项来设置组件的位置
# 同样你需要使用N,E,S,W以及它们的组合NE,SE,SW,NW来表示方位
Button(root, text="获取信息", width=10, command=show)\
.grid(row=3, column=0, sticky=W, padx=10, pady=5)
Button(root, text="退出", width=10, command=root.quit)\
.grid(row=3, column=1, sticky=E, padx=10, pady=5)
mainloop()
如果想设计一个密码输入框,即使用星号(*)代替用户输入的内 容,只需要设置show选项即可:
from tkinter import *
root = Tk()
Label(root, text="账号:").grid(row=0)
Label(root, text="密码:").grid(row=1)
v1 = StringVar()
v2 = StringVar()
e1 = Entry(root, textvariable=v1)
e2 = Entry(root, textvariable=v2, show="*")
e1.grid(row=0, column=1, padx=10, pady=5)
e2.grid(row=1, column=1, padx=10, pady=5)
def show():
print("账号:%s" % v1.get())
print("密码:%s" % v2.get())
e1.delete(0, END)
e2.delete(0, END)
Button(root, text="芝麻开门", width=10, command=show)\
.grid(row=3, column=0, sticky=W, padx=10, pady=5)
Button(root, text="退出", width=10, command=root.quit)\
.grid(row=3, column=1, sticky=E, padx=10, pady=5)
mainloop() 计算器: 验证功能
启用验证的“开关”是validate选项,该选项可以设置的值如表

其次是为validatecommand选项指定一个验证函数,该函数只能返回 True或False表示验证的结果。一般情况下验证函数只需要知道输入框的 内容即可,可以通过Entry组件的get()方法获得该字符串。 在下面的例子中,在第一个输入框中输入“花生米”,并通过Tab键 将焦点转移到第二个输入框的时候,验证功能被成功触发:
from tkinter import *
root = Tk()
def test1():
if e1.get() == "花生米":
print("正确!")
return True
else:
print("错误!")
e1.delete(0, END)#清空输入框
return False
#最后,invalidcommand选项指定的函数只有在validatecommand的返 回值为False的时候才被调用。 在下面的例子中,在第一个输入框中输入“小鱿鱼”,并通过Tab键 将焦点转移到第二个输入框,validatecommand指定的验证函数被触发并返回False,接着invalidcommand被触发:
def test2():
print('我被调用了..')
return True
v = StringVar()
e1=Entry(root,textvariable=v,validate="focusout",validatecommand=test1,invalidcommand=test2)#focusout焦点移除时
e2 = Entry(root)
e1.pack(padx=10, pady=10)
e2.pack(padx=10, pady=10)
mainloop()Tkinter为验证函数提供一些额外的选项

为了使用这些选项,可以这样写:
validatecommand=(f, s1, s2, ...)
其中,f是验证函数名,s1、s2、s3是额外的选项,这些选项会作为参数 依次传给f函数。在此之前,需要调用register()方法将验证函数包装起 来: from tkinter import * root = Tk() v = StringVar() def test(content, reason, name):#test多了三个参数,在validatecommand中
if content == "小甲鱼":
print("正确!")
print(content, reason, name)
return True
else:
print("错误!")
print(content, reason, name)
return False
testCMD = root.register(test)
e1 = Entry(root, textvariable=v, validate="focusout", validatecommand=(testCMD, '%P', '%v', '%W'))
e2 = Entry(root)
e1.pack(padx=10, pady=10)
e2.pack(padx=10, pady=10)
mainloop()
实现计算器
from tkinter import *
root = Tk()
frame = Frame(root)
frame.pack(padx=10, pady=10)
v1 = StringVar()
v2 = StringVar()
v3 = StringVar()
def test(content):
# 注意,这里你不能使用e1.get()或者v1.get()来获取输入的内容
# 因为validate选项指定为"key"的时候,有任何输入操作都会被拦截到这个函数中
# 也就是说先拦截,只有这个函数返回True,那么输入的内容才会到变量里边
# 所以我们要使用%P来获取最新的输入框内容
if content.isdigit():
return True
else:
return False
testCMD = root.register(test)
Entry(frame, textvariable=v1, width=10, validate="key", \
validatecommand=(testCMD, '%P')).grid(row=0, column=0)
Label(frame, text="+").grid(row=0, column=1)
Entry(frame, textvariable=v2, width=10, validate="key", \
validatecommand=(testCMD, '%P')).grid(row=0, column=2)
Label(frame, text="=").grid(row=0, column=3)
Entry(frame, textvariable=v3, width=10, validate="key", \
validatecommand=(testCMD, '%P')).grid(row=0, column=4)
def calc():
result = int(v1.get()) + int(v2.get())
v3.set(result)
Button(frame, text="计算结果", command=calc).grid(row=1, column=2, pady=5)
mainloop()
- end-
















