Contents

tkinter整理

参考资料

GUI 简介

Graphical User Interface 图形用户界面
一般由窗口、下拉菜单和对话框等控件组成,例如 QQ 的登录界面
GUI 让用户与计算机的交互过程变得简单舒适,它不只局限于技术层面,还涉及了美学、行为学、心理学等等领域

  • 发展史
    上世纪 70 年代,美国施乐研究中心完成 WIMP 程序
    1983 年,苹果公司发布电子图表软件 Lisa
    20 世纪初,微软相继发布 Windows 95、98、XP 等系统(微软开发的 Visual Basic 程序语言拥有许多 GUI 控件)

  • 应用
    软件产品、计算机操作系统界面
    车载系统、智能家居、电子数码

  • 开发工具
    较流行的 GUI 开发软件包有:Qt、GTK、wxWidgets、Electron 等等
    它们多数基于 C/C++ 开发

第一个程序

Tk interface,是 Python 自带的标准库模块
性能和功能都不及 Qt,但是可以用于快速开发一些简单的程序

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import tkinter as tk


# 创建主窗口
root_window = tk.Tk()

# 设置窗口名字
root_window.title('test')

# 获取电脑屏幕的分辨率大小
print(root_window.winfo_screenwidth(), root_window.winfo_screenheight())

# 设置窗口大小,宽x高,注意使用 "x"
root_window.geometry('450x300')

# 获取窗口的分辨率
root_window.update()
print(root_window.winfo_width(), root_window.winfo_height())

# 更改窗口的的 icon 图标
root_window.iconbitmap('C:/Users/Administrator/Desktop/test.ico')

# 设置主窗口的背景颜色
root_window["background"] = "#C9C9C9"
# 将窗口置于顶层
root_window.attributes('-topmost', True)
# 设置窗口的透明度
root_window.attributes('-alpha', 1)

# 添加文本,可以字体的前景色、背景色、字体类型和大小等
text = tk.Label(
    root_window,
    text="hello world",
    bg="yellow",
    fg="red",
    font=('Times', 20, 'bold italic')
)
# 将文本内容放置在主窗口内
text.pack()

# 添加按钮,可以设置按钮的文本
# command 参数设置关闭窗口的功能
button = tk.Button(
    root_window,
    text="关闭",
    command=root_window.quit
)
# 将按钮放置在主窗口内
button.pack(side="bottom")

# 开启主循环,让窗口处于显示状态
root_window.mainloop()

主窗口相当于画板,其他的控件都要建立在主窗口之上
主循环也称“消息循环”或“事件循环”

常用控件

主窗口

上面的示例介绍了一些常用的窗口使用方法
在 Tkinter 中提供了 事件绑定机制,还提供了 协议处理机制,指定是应用程序和窗口管理器之间的交互

  • 使用 WM_DELETE_WINDOW 协议

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    from tkinter import Tk
    from tkinter import messagebox
    
    
    # 创建主窗口
    window = Tk()
    
    # 定义回调函数
    # 当用户点击窗口右上角的 x 退出时,执行用户自定义的函数
    def QueryWindow():
        # 显示一个警告信息,点击确后,销毁窗口
        if messagebox.showwarning("警告", "出现了一个错误"):
            # 这里必须使用 destory() 关闭窗口
            window.destroy()
    
    # 使用协议机制与窗口交互,并回调用户自定义的函数
    window.protocol('WM_DELETE_WINDOW', QueryWindow)
    window.mainloop()
    
  • 主窗口居中

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    import tkinter as tk
    
    
    window = tk.Tk()
    window.title('test')
    window.iconbitmap('C:/Users/Administrator/Desktop/test.ico')
    
    # 设置窗口大小变量
    width = 300
    height = 300
    screenwidth = window.winfo_screenwidth()
    screenheight = window.winfo_screenheight()
    
    # 根据屏幕尺寸计算布局参数
    size_geo = '%dx%d+%d+%d' % (width, height, (screenwidth-width)/2, (screenheight-height)/2)
    # geometry() 方法可改变主窗口的位置
    window.geometry(size_geo)
    window.mainloop()
    

Label 标签

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import tkinter as tk


window = tk.Tk()
window.title("test")
window.geometry('400x200')
window.iconbitmap('C:/Users/Administrator/Desktop/test.ico')
label = tk.Label(
    window,
    text="hello world",
    font=('宋体', 20, 'bold italic'),
    bg="#7CCD7C",
    # 设置标签内容区大小
    width=30,height=5,
    # 设置填充区距离、边框宽度和其样式(凹陷式)
    padx=10, pady=15, borderwidth=10, relief="sunken"
)
label.pack()
window.mainloop()
  • Label 用于显示图片

    1
    2
    3
    4
    5
    
    photo = tk.PhotoImage(file = 'C:/Users/Administrator/Desktop/background.gif')
    print(type(photo))
    
    # 将图片放在主窗口的右边
    lab = tk.Label(window, image=photo).pack(side="right")
    

    注意:不同版本的 Tkinter 支持的图片的格式可能不同

  • Message 控件

    功能与 Label 类似,可以显示多行不可编辑的文本信息,会自动分行

    1
    2
    3
    4
    5
    6
    7
    
    txt = "这是一串很长的文字这是一串很长的文字这是一串很长的文字这是一串很长的文字这是一串很长的文字这是一串很长的文字这是一串很长的文字这是一串很长的文字"
    msg = tk.Message(
        window,
        text=txt,
        width=60,
        font=('微软雅黑', 10, 'bold')
    )
    

Button 按钮

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import tkinter as tk


window = tk.Tk()
# 创建图片对象
im = tk.PhotoImage(file='C:/Users/Administrator/Desktop/按钮.gif')

# 设置按钮回调函数
def callback():
    print("click me!")
    tk.messagebox.showinfo(title='温馨提示', message='已点击')

b = tk.Button(
    window,
    text="点击执行回调函数",
    bg='#7CCD7C', width=20, height=5,
    command=callback
).pack()

tk.mainloop()
  • 为 Button 控件添加一张背景图片

    1
    2
    3
    4
    5
    6
    7
    8
    
    # 创建图片对象
    im = tk.PhotoImage(file='C:/Users/Administrator/Desktop/按钮.gif')
    
    b = tk.Button(
        ......
        image=im,
        ......
    )
    
  • 动态文本

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    
    import tkinter as tk
    import time
    
    
    window = tk.Tk()
    window.iconbitmap('C:/Users/Administrator/Desktop/test.ico')
    window.geometry('450x150+100+100')
    window.resizable(0, 0)
    window.title('动态时钟')
    
    def gettime():
        # 获取当前时间
        dstr.set(time.strftime("%H:%M:%S"))
        # 每隔 1s 调用一次 gettime() 函数获取时间
        window.after(1000, gettime)
    
    # 生成动态字符串
    dstr = tk.StringVar()
    # 利用 textvariable 来实现文本变化
    lb = tk.Label(
        window,
        textvariable=dstr,
        fg='green',
        font=("微软雅黑",85)
    )
    lb.pack()
    
    # 调用生成时间的函数
    gettime()
    window.mainloop()
    

Entry 输入

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import tkinter as tk


window = tk.Tk()
window.geometry('250x100')
window.title("test")
window.iconbitmap('C:/Users/Administrator/Desktop/test.ico')
window.resizable(0, 0)

# 创建输入框控件
entry = tk.Entry(window)
# 放置输入框,并设置位置
entry.pack(padx=20, pady=20)
# 删除所有字符
entry.delete(0, tk.END)
# 插入默认文本
entry.insert(0, 'hello world')
# 获取输入框字符串
print(entry.get())

window.mainloop()
  • 简易的登录页
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 新建文本标签
labe1 = tk.Label(window,text="账号:")
labe2 = tk.Label(window,text="密码:")
# grid() 控件布局管理器,以行、列的形式对控件进行布局
labe1.grid(row=0)
labe2.grid(row=1)
# 为上面的文本标签,创建两个输入框控件
entry1 = tk.Entry(window)
entry2 = tk.Entry(window)
# 对控件进行布局管理,放在文本标签的后面
entry1.grid(row=0, column=1)
entry2.grid(row=1, column=1)
  • 添加校验功能
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# 创建验证函数
def check():
    if entry1.get().startsWith("user"):
        messagebox.showinfo("输入正确")
        return True
    else:
        messagebox.showwarning("输入不正确")
        entry1.delete(0, tk.END)
        return False

# 创建动态字符串
Dy_String = tk.StringVar()
# 使用验证参数 validata,参数值为 focusout
# 当失去焦点的时候,验证输入框内容是否正确
entry1 = tk.Entry(
    window,
    textvariable = Dy_String,
    validate ="focusout",
    validatecommand=check
)
entry2 = tk.Entry(window)
  • spinbox 输入框
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 数字输入框
w = tk.Spinbox(
    window,
    from_=0, to=20, increment=2,
    width = 15, bg='#9BCD9B'
)

# 字符选择
# 使用 values 参数以元组的形式进行传参
strings = tk.Spinbox(
    window,
    values=('Python','java','C语言','PHP')
)
strings.pack()
  • 容器示例
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
from tkinter import *


# 创建窗体
window = tk.Tk()
window.geometry('300x300')
window.title("test")
window.iconbitmap('C:/Users/Administrator/Desktop/test.ico')
window.resizable(0, 0)

# 创建一个容器来包括其他控件
frame = Frame(window)

# 创建一个计算器
def calc() :
    # 用户输入的表达式,计算结果后转换为字符串
    result = "= " + str(eval(expression.get()))
    # 将计算的结果显示在 Label 控件上
    label.config(text=result)

label = Label (frame)
entry = Entry (frame)
# 读取用户输入的表达式
expression = StringVar()
# 将用户输入的表达式显示在 Entry 控件上
entry["textvariable"] = expression

# 当用户输入完毕后,单击此按钮即计算表达式的结果
button1 = Button(frame, text="等 于", command=calc)
# 设置 Entry 控件为焦点所在
entry.focus()

frame.pack()
entry.pack()
label.pack(side="left")
button1.pack(side="right")

frame.mainloop()

Text 文本框

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from tkinter import *


window = Tk()
window.title("test")
window.iconbitmap('C:/Users/Administrator/Desktop/test.ico')
window.geometry('400x300')

# 创建一个文本控件
text = Text(window, width=50, height=20, undo=True, autoseparators=False)
text.grid()
# INSERT 光标处插入;END 末尾处插入
text.insert(INSERT, 'hello world! Welcome to Tkinter world!')

# 定义撤销和恢复方法
def backout():
    text.edit_undo()
def regain():
    text.edit_redo()

# 定义撤销和恢复按钮
Button(window, text = '撤销', command = backout).grid(row=3, column=0, sticky="w", padx=10, pady=5)
Button(window, text = '恢复', command = regain).grid(row=3, column=0, sticky="e", padx=10, pady=5)

window.mainloop()
  • Tag

给一定范围内的文字起一个标签名,通过该标签名能操控某一范围内的文字
比如修改文本的字体、尺寸和颜色

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 创建一个 Text 控件
text = Text(window)
# 在 Text 控件内插入一段文字
# INSERT 表示在光标处插入,END 表示在末尾处插入
text.insert(INSERT, "梦影雾花,尽是虚空,因心想杂乱,方随逐诸尘,不如万般皆散\n\n")
text.insert(INSERT, "\n\n")
# 在 Text 控件内插入一个按钮
button = Button(text, text="关闭", command=window.quit)
text.window_create(END, window=button)

# 填充水平和垂直方向
# 这里设置 expand 为 True 否则不能垂直方向延展
text.pack(fill=BOTH, expand=True)
# 在第一行文字的第 0 个字符到第 6 个字符处插入标签,标签名称为"name"
text.tag_add("name", "1.0", "1.6")
# 将插入的按钮设置其标签名为 "button"
text.tag_add("button", button)
# 使用 tag_config() 来改变标签 "name" 的前景与背景颜色,并加下画线,通过标签控制字符的样式
text.tag_config(
    "name",
    font=('微软雅黑', 18, 'bold'),
    background="yellow", foreground= "blue",
    underline=1
)
# 设置标签 "button" 的居中排列
text.tag_config("button", justify="center")
  • mark

通常被用来当作书签,它可以帮助用户快速找到内容的指定位置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
text = tk.Text(window, width=35, heigh=15)
text.pack()
text.insert("insert", "C语言中文网")
# 设置标记
text.mark_set("name", "1.end")
# 在标记之后插入相应的文字
text.insert("name", ",网址:c.biancheng.net")
# 跟着自动移动,往后插入,而不是停留在原位置
text.insert("name", ",欢迎光临")
# 若使用 mark_unset() 可以删除指定的标记
# text.mark_unset("name")
# 但使用delete来清楚所有的内容, mark 标记依旧会存在
# text.delete("1.0","end")
# 依然可以使用 name标记来插入
# text.insert("name", "Python答疑")
# 显示窗口
window.mainloop()

列表框和组合框

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from tkinter import *


window = Tk()
window.title("test")
window.geometry('400x200')
window.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')

# 创建滚动条
s = Scrollbar(window)
# 设置垂直滚动条显示的位置,使得滚动条,靠右侧;通过 fill 沿着 Y 轴填充
s.pack(side = RIGHT, fill = Y)

# 创建列表选项
listbox1 = Listbox(
    window,
    selectmode = MULTIPLE,    # 多选模式
    height = 5,
    yscrollcommand = s.set
)
listbox1.pack()
# 设置滚动条
# 通过绑定 Scollbar 组件的 command 参数实现
# 使用 yview 使其在垂直方向上滚动 Listbox 组件的内容
s.config(command = listbox1.yview)

# i 表示索引值,item 表示值,根据索引值的位置依次插入
for i, item in enumerate(["C","C++","C#","Python","Java"]):
    listbox1.insert(i, item)
listbox1.insert(0, '编程学习')  # 在第一个位置插入一段字符串
listbox1.delete(4)  # 删除第 4 个位置处的索引

# 显示窗口
window.mainloop()
  • combobox 下拉菜单栏
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 创建下拉菜单
cbox = ttk.Combobox(window)
# 使用 grid() 来控制控件的位置
cbox.grid(row = 1, sticky="NW")
# 设置下拉菜单中的值
cbox['value'] = ('C','C#','Go','Python','Java')
#通过 current() 设置下拉菜单选项的默认值
cbox.current(3)

# 为下拉菜单栏绑定选择事件
cbox.bind("<<ComboboxSelected>>",func)

单选框

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
def select():
    dict = {1:'C语言中文网',2:'菜鸟教程',3:'W3SCHOOL',4:'微学苑'}
    strings = '您选择了' + dict.get(v.get()) + ',祝您学习愉快'
    print(strings)

site = [('美团外卖',1),
        ('饿了么外卖',2),
        ('美团闪购',3),
        ('艾奇外卖',4)]

# IntVar() 用于处理整数类型的变量
v = tk.IntVar()

for name, num in site:
    radio_button = tk.Radiobutton(window, text = name, variable = v, value =num, command=select)
    radio_button.pack(anchor = 'w')
  • 多选框
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 新建整型变量
CheckVar1 = IntVar()
CheckVar2 = IntVar()
CheckVar3 = IntVar()

# 设置三个复选框控件,使用variable参数来接收变量
check1 = Checkbutton(window, text="Python",font=('微软雅黑', 15,'bold'),variable = CheckVar1,onvalue=1,offvalue=0)
check2 = Checkbutton(window, text="C语言",font=('微软雅黑', 15,'bold'),variable = CheckVar2,onvalue=1,offvalue=0)
check3 = Checkbutton(window, text="Java",font=('微软雅黑', 15,'bold'),variable = CheckVar3,onvalue=1,offvalue=0)

# 选择第一个为默认选项
# check1.select ()
check1.pack(side = LEFT)
check2.pack(side = LEFT)
check3.pack(side = LEFT)

# 定义执行函数
def study():
    # 没有选择任何项目的情况下
    if (CheckVar1.get() == 0 and CheckVar2.get() == 0 and CheckVar3.get() == 0):
        s = '您还没选择任语言'
    else:
        s1 = "Python" if CheckVar1.get() == 1 else ""
        s2 = "C语言" if CheckVar2.get() == 1 else ""
        s3 = "Java" if CheckVar3.get() == 1 else ""
        s = "您选择了%s %s %s" % (s1, s2, s3)
     #设置标签 lb2 的字体
    lb2.config(text=s)

btn = Button(window,text="选好了",bg='#BEBEBE',command=study)
btn.pack(side = LEFT)
# 该标签,用来显示选择的文本
lb2 = Label(window,text='',bg ='#9BCD9B',font=('微软雅黑', 11,'bold'),width = 5,height=2)
lb2.pack(side = BOTTOM, fill = X)

Scale 滑块

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 添加一个 Scale 控件
# 默认垂直方向,步长设置为 5,长度为 200,滑动块的大小为 50,最后使用 label 参数文本
s = Scale(
    window,
    label='音量控制',
    from_=100, to=0, resolution=5,
    length=200, sliderlength=20,
    orient=tk.HORIZONTAL,    # 设置 Scale 控件平方向显示
    tickinterval=9,    # 设置刻度滑动条的间隔
)
s.pack()

# 设置滑块的位置
s.set(value=15)

Canvas 画布

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import tkinter as tk


window = tk.Tk()
window.title("test")
window.geometry('400x200')
# 窗口不允许改变
window.resizable(0, 0)
window.iconbitmap('C:/Users/Administrator/Desktop/test.ico')
# 创建画布
canvas = tk.Canvas(
    window,
    bg='#CDC9A5',
    height=200,
    width=300
)
canvas.pack()
window.mainloop()
  • 在画布(Canvas 控件)上进行绘制

还可以绘制多边形

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 创建画布
canvas = tk.Canvas(
    window,
    bg='#CDC9A5',
    height=200,
    width=300
)
canvas.pack()

# 设置坐标点,此处可以元组的形式来设置坐标点
point = [(10,20),(20,30),(30,40),(40,100),(80,120),(150,90)]
# 创建画布,添加线条
# fill 参数指定填充的颜色,如果为空字符串,则表示透明
# dash 参数表示用来绘制虚线轮廓,元组参数,分别代表虚线中线段的长度和线段之间的间隔
# arrow 设线段的箭头样式,默认不带箭头,参数值 first 表示添加箭头带线段开始位置,last表示到末尾占位置,both表示两端均添加
# smooth 布尔值参数,表示是否以曲线的样式划线,默认为 False
# width 控制线宽
line1 = canvas.create_line(point,fill="purple",dash=(1,1),arrow=LAST,width=5)
print('线段line1的画布id号:',line1)

line2 = canvas.create_line(point,fill="red",arrow=BOTH,smooth=TRUE,width=5)
print('线段line2的画布id号:',line2)

# 移动其中一条线段,只需要更改其坐标就可以,使用 coords()方法移动曲线
canvas.coords(line2,50,30,25,35,35,40,50,120,60,170,10,180)
  • 在画布上添加图片、文本
1
2
3
4
5
6
7
8
# 展示图片,使用 PhotoImage() 来加载图片
img = PhotoImage(file="C:/Users/Administrator/Desktop/test.gif")
imgcv = canvas.create_image(30,150,image=img,anchor=W)
txtcv = canvas.create_text(30,220,text = "图片预览",fill ='#7CCD7C',anchor = W,font=('微软雅黑',15,'bold'))

# 调用 delete() 删除画布对象
# 若传入 ALL,则删除所有的画布对象
canvas.delete(imgcv)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 绑定一个执行函数,当点击菜单项的时候会显示一个消息对话框
def menuCommand() :
    tkinter.messagebox.showinfo("主菜单栏", "你正在使用菜单栏")

# 创建一个主目录菜单
main_menu = Menu(window)
# 创建一个子菜单,同时不添加分割线
filemenu = Menu (main_menu, tearoff=False)
# 新增"文件"菜单的菜单项,并使用 accelerator 设置菜单项的快捷键
filemenu.add_command(label="新建",command=menuCommand,accelerator="Ctrl+N")
filemenu.add_command(label="打开",command=menuCommand, accelerator="Ctrl+O")
filemenu.add_command(label="保存",command=menuCommand, accelerator="Ctrl+S")
# 添加一条分割线
filemenu.add_separator()
filemenu.add_command(label="退出",command=window.quit)
# 在主目录菜单上新增"文件"选项,并通过menu参数与下拉菜单绑定
mainmenu.add_cascade (label="文件", menu=filemenu)

# 新增命令菜单项,使用 add_command() 实现
main_menu.add_command(label="编辑", command=menuCommand)
main_menu.add_command(label="格式", command=menuCommand)
main_menu.add_command(label="查看", command=menuCommand)
main_menu.add_command(label="帮助", command=menuCommand)
# 显示菜单
window.config(menu=main_menu)
1
2
3
4
5
6
7
# 绑定键盘事件,按下键盘上的相应的键时都会触发执行函数
window.bind("<Control-n>", menuCommand)
window.bind("<Control-N>", menuCommand)
window.bind("<Control-o>", menuCommand)
window.bind("<Control-O>", menuCommand)
window.bind("<Control-s>", menuCommand)
window.bind("<Control-S>", menuCommand)
  • 鼠标右键的弹出窗
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 创建一个弹出菜单
menu = tk.Menu(window, tearoff=False)
menu.add_command(label="新建", command=func)
menu.add_command(label="复制", command=func)
menu.add_command(label="粘贴", command=func)
menu.add_command(label="剪切", command=func)

# 定义事件函数
def command(event):
    # 使用 post()在指定的位置显示弹出菜单
    menu.post(event.x_root, event.y_root)

# 绑定鼠标右键
# <Button-3> 表示点击鼠标的右键,1 表示左键,2 表示点击中间的滑轮
window.bind("<Button-3>", command)

Scrollbar 滚动条

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# 创建一个滚动条控件,默认为垂直方向
sbar1 = tk.Scrollbar(window)
# 将滚动条放置在右侧,并设置当窗口大小改变时滚动条会沿着垂直方向延展
sbar1.pack(side=RIGHT, fill=Y)

# 创建水平滚动条,默认为水平方向,当拖动窗口时会沿着X轴方向填充
sbar2 = tk.Scrollbar(window, orient=HORIZONTAL)
sbar2.pack(side=BOTTOM, fill=X)

# 创建列表框控件,并添加两个滚动条(分别在垂直和水平方向)
mylist = tk.Listbox(window, xscrollcommand = sbar2.set, yscrollcommand = sbar1.set)
for i in range(30):
    mylist.insert(END, '第'+ str(i+1)+'次:'+'C语言中文网,网址为:c.biancheng.net'+ '\n' )
# 当窗口改变大小时会在X与Y方向填满窗口
mylist.pack(side=LEFT, fill = BOTH)
# 使用 command 关联控件的 yview、xview方法
sbar1.config(command =mylist.yview)
sbar2.config(command = mylist.xview)

对话框

  • 文件选择

实现从本地选择文件的功能

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from tkinter import *
import tkinter.filedialog


def askfile():
    # 从本地选择一个文件,并返回文件的目录
    filename = tkinter.filedialog.askopenfilename()
    if filename != '':
        lb.config(text = filename)
    else:
        lb.config(text = '您没有选择任何文件')

window = Tk()
window.config(bg='#87CEEB')
window.title("test")
window.geometry('400x200+300+300')
window.iconbitmap('C:/Users/Administrator/Desktop/test.ico')

btn = Button(window,text='选择文件',relief=RAISED,command=askfile)
btn.grid(row=0,column=0)

lb = Label(window,text='',bg='#87CEEB')
lb.grid(row=0,column=1,padx=5)

window.mainloop()
  • 颜色选择
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from tkinter import colorchooser


def callback():
    # 打开颜色对话款
    colorvalue = tk.colorchooser.askcolor()
    # 在颜色面板点击确定后,会在窗口显示二元组颜色值
    lb.config(text='颜色值:'+ str(colorvalue))

lb = tk.Label(window,text='',font=('宋体',10))
lb.pack()

tk.Button(window, text="点击选择颜色", command=callback, width=10, bg='#9AC0CD').pack()
  • Messagebox 消息对话框
1
2
3
4
5
import tkinter.messagebox


result = tkinter.messagebox.askokcancel ("提示", "你确定要关闭窗口吗? ")
print(result)    # 返回布尔值参数

布局

常用方法

  • pack

默认情况下,以添加时的先后顺序,自上而下、逐行排列,并且居中显示

1
2
3
4
# 沿着水平方向填充
# 与其他标签的上下距离为 5 个像素
lb_blue = Label(window,text="蓝色",bg="blue",fg='#ffffff',relief=GROOVE)
lb_blue.pack(fill=X,pady='5px')
  • grid

基于网格式的布局管理方法
可以把窗口看成一张表格,往单元格中放置控件

注意
不能同时使用 pack 和 grid 方法

1
2
3
4
5
6
7
8
# 在第 5 行第 11 列添加一个 Label 标签
Label(
    window,
    text="test",
    fg='blue',
    font=('楷体',12,'bold')
).grid(row=4, column=10)
# rowspan 参数控制占用的单元格个数
  • place

直接指定控件在窗体内的绝对位置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
from tkinter import *


# 主窗口
window = Tk()
window.title("test")
window.iconbitmap('C:/Users/Administrator/Desktop/test.ico')
# 创建一个 frame 窗体对象,用来包裹标签
frame = Frame(window, relief=SUNKEN, borderwidth=2, width=450, height=250)
# 在水平、垂直方向上填充窗体
frame.pack(side=TOP, fill=BOTH, expand=1)

Label1 = Label(frame, text="位置1",bg='blue',fg='white')
# 设置第一个标签位于距离窗体左上角的位置(40,40)
# 大小为 width,height
# 默认以 NW 左上角作为参照
Label1.place(x=40,y=40, width=60, height=30)

# relx、rely 设置相对于窗体的倍数的长宽
# relwidth、relheight 设置相对于窗体的倍数的坐标

划分区域

  • Frame

本质上也是一个矩形窗体,也需要位于主窗口内
主窗口内可以放置多个 Frame 控件,并且每个 Frame 中还可以嵌套一个或者多个 Frame,从而将主窗口界面划分成多个区域

  • LabelFrame

类似的,但是多了边框和标题

  • PanedWindow

可以自己调节每块区域的大小
可以添加一个手柄,设置分割线样式,拖动改变大小

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# 创建一个水平方向的 panedwindow
p_window1 = tk.PanedWindow(window)
p_window1.pack(fill=tk.BOTH, expand=1)

# 在窗口区的左侧添加两个水平方向的 Label
left1 = tk. Label(p_window1, text='C语言中文网', bg='#7CCD7C', width=10, font=('微软雅黑',15))
p_window1.add(left1)
left2 = tk.Label(p_window1, text='网址:c.biancheng.net', bg='#9AC0CD', width=10, font=('微软雅黑',15))
p_window1.add(left2)

# 创建一个垂直方向的 panedwindow
# 并添加一个手柄,设置分割线样式
p_window2 = tk.PanedWindow(orient=tk.VERTICAL,showhandle=True,sashrelief='sunken')
# 添加到 p_window1 中
p_window1.add(p_window2)

# 在 p_window2 中添加两个垂直方向的标签
top_label = tk.Label(p_window2, text='教程', bg='#7171C6', height=8, font=('宋体',15))
p_window2.add(top_label)
bottom_label = tk.Label(p_window2, text='辅导班', bg='#8968CD', font=('宋体',15))
p_window2.add(bottom_label)
  • Toplevel

子窗体控件,会脱离根窗口另行创建一个独立窗口
即弹出框

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
def create_toplevel():
    top = tk.Toplevel()
    top.title("test")
    top.geometry('300x200+100+100')
    top.iconbitmap('C:/Users/Administrator/Desktop/test.ico')
    # 多行文本显示Message控件
    msg = tk.Label(top, text="helloworld!",bg='#9BCD9B', font=('宋体',15))
    msg.pack()

tk.Button(window, text="点击创建Toplevel组件", width=20,height=3,command=create_toplevel).pack()