Tkinter 简介
Tkinter(即 tk interface,简称"Tk")本质上是对 Tcl/Tk 软件包的 Python 接口封装,它是 Python 官方推荐的 GUI 工具包,属于 Python 自带的标准库模块,当您安装好 Python 后,就可以直接使用它,而无须另行安装。
作为一款 Python GUI 工具,Tkinter 拥有良好的跨平台性,支持 Windows、Linux、Mac 平台,它传承了 Python 语法简洁、代码易读的基本特点。
与其他编程语言的 GUI 工具包相比,Tkinter 编码效率高,能够实现快速开发的目的,非常适合初学者学习。Tkinter 使用纯 Python 语言开发,与 C/C++ 开发的 Qt 框架相比,Tkinter 有自身的局限性,比如性能、功能丰富程度等都不及 Qt,因此它只适合开发一些简单的程序,比如计算器的界面,或者一个简易的聊天窗口等。
Tkinter 快速入门
Tkinter 程序至少应包含以下四个部分:
-
导入 tkinter 模块
-
创建主窗口,也称 root 窗口(即根窗口)
-
添加人机交互控件,同时编写相应的事件函数
-
通过主循环(mainloop)来显示主窗口
第一章节:Tkinter 快速入门
import tkinter
调用Tk()创建主窗口
root_window = tkinter.Tk()
给主窗口起一个名字,也就是窗口的名字
root_window.title('Tkinter 快速入门')
开启主循环,让窗口处于显示状态
root_window.mainloop()
上述代码创建了一个没有添加任何交互控件的 Tkinter 程序,它也是最简单的 GUI 程序。这里的主窗口相当于画板,其他的控件都要建立在主窗口之上。主循环也称"消息循环"或"事件循环"其主要作用是让主窗口处于显示状态。
下面通过Tkinter实现简单登入页面,代码如下所示:
# 第二章节:Tkinter 实现简单登入页面
import tkinter
import tkinter
import tkinter.messagebox
# 创建应用程序窗口
root = tkinter.Tk()
varName = tkinter.StringVar()
varName.set('')
varPwd = tkinter.StringVar()
varPwd.set('')
# 创建标签
labelName = tkinter.Label(root, text='用户名:', justify=tkinter.RIGHT, width=80)
# 将标签放到窗口上
labelName.place(x=10, y=5, width=80, height=20)
# 创建文本框,同时设置关联的变量
entryName = tkinter.Entry(root, width=80, textvariable=varName)
entryName.place(x=100, y=5, width=80, height=20)
labelPwd = tkinter.Label(root, text='密 码:', justify=tkinter.RIGHT, width=80)
labelPwd.place(x=10, y=30, width=80, height=20)
# 创建密码文本框
entryPwd = tkinter.Entry(root, show='*', width=80, textvariable=varPwd)
entryPwd.place(x=100, y=30, width=80, height=20)
# 登录按钮事件处理函数
def login():
# 获取用户名和密码
name = entryName.get()
pwd = entryPwd.get()
if name == 'admin' and pwd == '123456':
tkinter.messagebox.showinfo(title='Python tkinter', message='登录成功!')
else:
tkinter.messagebox.showerror(title='Python tkinter', message='登录失败')
# 创建按钮组件,同时设置按钮事件处理函数
buttonOk = tkinter.Button(root, text='登录', command=login)
buttonOk.place(x=30, y=70, width=50, height=20)
# 取消按钮的事件处理函数
def cancel():
# 清空用户输入的用户名和密码
varName.set('')
varPwd.set('')
buttonCancel = tkinter.Button(root, text='取消', command=cancel)
buttonCancel.place(x=90, y=70, width=50, height=20)
# 启动消息循环
root.mainloop()
效果截图:
下面对登入页面进行简单分析:
1) 主窗口设置
主要对主窗口进行实例化
# 创建应用程序窗口
root = tkinter.Tk()
2) 添加标签控件和文本输入框
上述程序中,我们添加二个标签控件和二个文本输入框。需要注意的是,当成功创建标签(文本)对象后,使用 place 方法将其放置在主窗口内(place 方法又称绝对/相对布局管理器)。
# 创建标签
labelName = tkinter.Label(root, text='用户名:', justify=tkinter.RIGHT, width=80)
# 将标签放到窗口上
labelName.place(x=10, y=5, width=80, height=20)
# 创建文本框,同时设置关联的变量
entryName = tkinter.Entry(root, width=80, textvariable=varName)
entryName.place(x=100, y=5, width=80, height=20)
labelPwd = tkinter.Label(root, text='密 码:', justify=tkinter.RIGHT, width=80)
labelPwd.place(x=10, y=30, width=80, height=20)
# 创建密码文本框
entryPwd = tkinter.Entry(root, show='*', width=80, textvariable=varPwd)
entryPwd.place(x=100, y=30, width=80, height=20)
3) 添加按钮
添加按钮的逻辑和添加文本标签类似,值得注意的是,按钮控件通过command
参数实现了"登入"/"取消"功能。
# 登录按钮事件处理函数
def login():
# 获取用户名和密码
name = entryName.get()
pwd = entryPwd.get()
if name == 'admin' and pwd == '123456':
tkinter.messagebox.showinfo(title='Python tkinter', message='登录成功!')
else:
tkinter.messagebox.showerror(title='Python tkinter', message='登录失败')
# 创建按钮组件,同时设置按钮事件处理函数
buttonOk = tkinter.Button(root, text='登录', command=login)
buttonOk.place(x=30, y=70, width=50, height=20)
# 取消按钮的事件处理函数
def cancel():
# 清空用户输入的用户名和密码
varName.set('')
varPwd.set('')
buttonCancel = tkinter.Button(root, text='取消', command=cancel)
buttonCancel.place(x=90, y=70, width=50, height=20)
Tkinter常用控件和属性
Tkinter 的提供各种控件,如按钮,标签和文本框,一个 GUI 应用程序中使用。这些控件通常被称为控件或者部件。
Tkinter控件
目前有 15 种 Tkinter 的部件。我们提出这些部件以及一个简短的介绍,在下面的表:
控件 | 描述 |
---|---|
Button | 按钮控件;在程序中显示按钮。 |
Canvas | 画布控件;显示图形元素如线条或文本 |
Checkbutton | 多选框控件;用于在程序中提供多项选择框 |
Entry | 输入控件;用于显示简单的文本内容 |
Frame | 框架控件;在屏幕上显示一个矩形区域,多用来作为容器 |
Label | 标签控件;可以显示文本和位图 |
Listbox | 列表框控件;在Listbox窗口小部件是用来显示一个字符串列表给用户 |
Menubutton | 菜单按钮控件,由于显示菜单项。 |
Menu | 菜单控件;显示菜单栏,下拉菜单和弹出菜单 |
Message | 消息控件;用来显示多行文本,与label比较类似 |
Radiobutton | 单选按钮控件;显示一个单选的按钮状态 |
Scale | 范围控件;显示一个数值刻度,为输出限定范围的数字区间 |
Scrollbar | 滚动条控件,当内容超过可视化区域时使用,如列表框。. |
Text | 文本控件;用于显示多行文本 |
Toplevel | 容器控件;用来提供一个单独的对话框,和Frame比较类似 |
Spinbox | 输入控件;与Entry类似,但是可以指定输入范围值 |
PanedWindow | PanedWindow是一个窗口布局管理的插件,可以包含一个或者多个子控件。 |
LabelFrame | labelframe 是一个简单的容器控件。常用与复杂的窗口布局。 |
tkMessageBox | 用于显示你应用程序的消息框。 |
控件通用基本属性
在 Tkinter 中不同的控件受到各自参数的约束(即参数),所有控件既有相同属性,也有各自独有的属性。我们先对这些控件的共用属性做简单介绍,如下表所示:
属性名称 | 说明 |
---|---|
anchor | 定义控件或者文字信息在窗口内的位置 |
bg | bg 是 background 的缩写,用来定义控件的背景颜色,参数值可以颜色的十六进制数,或者颜色英文单词 |
bitmap | 定义显示在控件内的位图文件 |
borderwidth | 定于控件的边框宽度,单位是像素 |
command | 该参数用于执行事件函数,比如单击按钮时执行特定的动作,可将执行用户自定义的函数 |
cursor | 当鼠标指针移动到控件上时,定义鼠标指针的类型,字符换格式,参数值有 crosshair(十字光标)watch(待加载圆圈)plus(加号)arrow(箭头)等 |
font | 若控件支持设置标题文字,就可以使用此属性来定义,它是一个数组格式的参数 (字体,大小,字体样式) |
fg | fg 是 foreground 的缩写,用来定义控件的前景色,也就是字体的颜色 |
height | 该参数值用来设置控件的高度,文本控件以字符的数目为高度(px),其他控件则以像素为单位 |
image | 定义显示在控件内的图片文件 |
justify | 定义多行文字的排列方式,此属性可以是 LEFT/CENTER/RIGHT |
padx/pady | 定义控件内的文字或者图片与控件边框之间的水平/垂直距离 |
relief | 定义控件的边框样式,参数值为FLAT(平的)/RAISED(凸起的)/SUNKEN(凹陷的)/GROOVE(沟槽桩边缘)/RIDGE(脊状边缘) |
text | 定义控件的标题文字 |
state | 控制控件是否处于可用状态,参数值默认为 NORMAL/DISABLED,默认为 NORMAL(正常的) |
width | 用于设置控件的宽度,使用方法与 height 相同 |
Tkinter主窗口
主窗口是一切控件的基础,所有的控件的都需要通过主窗口来显示。
创建一个空白窗口
# 第三章节:Tkinter 创建空白页面
from tkinter import *
# 创建一个主窗口对象
window = Tk()
# 调用mainloop()显示主窗口
window.mainloop()
窗口常用方法
下表列出了窗口的常用方法,其中 window 代表主窗口对象:
函数 | 说明 |
---|---|
window.title("my title") | 接受一个字符串参数,为窗口起一个标题 |
window.resizable() | 是否允许用户拉伸主窗口大小,默认为可更改,当设置为 resizable(0,0)或者resizable(False,False)时不可更改 |
window.geometry() | 设定主窗口的大小以及位置,当参数值为 None 时表示获取窗口的大小和位置信息。 |
window.quit() | 关闭当前窗口 |
window.update() | 刷新当前窗口 |
window.mainloop() | 设置窗口主循环,使窗口循环显示(一直显示,指导窗口被关闭) |
window.iconbitmap() | 设置窗口左上角的图标(图标是.ico文件类型) |
window.config(background ="red") | 设置窗口的背景色为红色,也可以接受 16 进制的颜色值 |
window.minsize(50,50) | 设置窗口被允许调整的最小范围,即宽和高各50 |
window.maxsize(400,400) | 设置窗口被允许调整的最大范围,即宽和高各400 |
window.attributes("-alpha",0.5) | 用来设置窗口的一些属性,比如透明度(-alpha)、是否置顶(-topmost)即将主屏置于其他图标之上、是否全屏(-fullscreen)全屏显示等 |
window.state("normal") | 用来设置窗口的显示状态,参数值 normal(正常显示),icon(最小化),zoomed(最大化), |
window.withdraw() | 用来隐藏主窗口,但不会销毁窗口。 |
window.iconify() | 设置窗口最小化 |
window.deiconify() | 将窗口从隐藏状态还原 |
window.winfo_screenwidth() window.winfo_screenheight() | 获取电脑屏幕的分辨率(尺寸) |
window.winfo_width() window.winfo_height() | 获取窗口的大小,同样也适用于其他控件,但是使用前需要使用 window.update() 刷新屏幕,否则返回值为1 |
window.protocol("协议名",回调函数) | 启用协议处理机制,常用协议有 WN_DELETE_WINDOW,当用户点击关闭窗口时,窗口不会关闭,而是触发回调函数。 |
# 第四章节:Tkinter 主窗口相关函数
from tkinter import *
window = Tk()
# 设置窗口title
window.title('Tkinter 快速入门')
# 设置窗口大小:宽x高,注,此处不能为 "*",必须使用 "x"
window.geometry('450x300')
# 获取电脑屏幕的大小
print("电脑的分辨率是%dx%d"%(window.winfo_screenwidth(), window.winfo_screenheight()))
# 要求窗口的大小,必须先刷新一下屏幕
window.update()
print("窗口的分辨率是%dx%d"%(window.winfo_width(), window.winfo_height()))
# 如使用该函数则窗口不能被拉伸
# window.resizable(0,0)
# 改变背景颜色
window.config(background="#6fb765")
# 设置窗口处于顶层
window.attributes('-topmost', True)
# 设置窗口的透明度
window.attributes('-alpha',1)
# 设置窗口被允许最大调整的范围,与resizble()冲突
window.maxsize(600, 600)
# 设置窗口被允许最小调整的范围,与resizble()冲突
window.minsize(50, 50)
# 更改左上角窗口的的icon图标,加载C语言中文网logo标
window.iconbitmap("img/1.png")
# 进入主循环,显示主窗口
window.mainloop()
设置主窗位置
实际情况中窗口的位置在电脑屏幕的居中位置,我们应该如何处理呢?其实很简单,通过窗口对象的 geometry() 方法即可改变主窗口的位置,其语法格式如下:
geometry('450x400+300+200')
上述代码表示,设置主窗口的宽度为 450,高度为 400,同时窗口距离左边屏幕的距离为 300(以像素为单位),距离屏幕顶部的距离为 200,这里我们将带"+"的参数值称为"位置参数",当然,您也可以将它们设置为负数,如下所示:
geometry('+-1500+-2000')
当设置了一个超过屏幕的负参数值时,主窗口会被移动至"屏幕之外",此时就看不到主窗口了,这也是隐藏窗口的一种方法。
# 第五章节:Tkinter 主窗口屏幕居中显示
import tkinter as tk
window = tk.Tk()
# 设置窗口大小变量
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)
window.geometry(size_geo)
window.mainloop()
Tkinter 控件使用指南
Tkinter Label标签控件
Label(标签)控件,是 Tkinter 中最常使用的一种控件,主要用来显示窗口中的文本或者图像,并且不同的 Lable(标签)允许设置各自不同的背景图片。
下面对 Label(标签)的常用属性做简单介绍:
属性名称 | 说明 |
---|---|
anchor | 控制文本(或图像)在 Label 中显示的位置(方位),通过方位的英文字符串缩写(n、ne、e、se、s、sw、w、nw、center)实现定位,默认为居中(center) |
bg | 用来设置背景色 |
bd | 即 borderwidth 用来指定 Label 控件的边框宽度,单位为像素,默认为 2 个像素 |
bitmap | 指定显示在 Label 控件上的位图,若指定了 image 参数,则该参数会被忽略 |
compound | 控制 Lable 中文本和图像的混合模式,若选项设置为 CENTER,则文本显示在图像上,如果将选项设置为 BOTTOM、LEFT、RIGHT、TOP,则图像显示在文本旁边。 |
cursor | 指定当鼠标在 Label 上掠过的时候,鼠标的的显示样式,参数值为 arrow、circle、cross、plus |
disableforeground | 指定当 Label 设置为不可用状态的时候前景色的颜色 |
font | 指定 Lable 中文本的 (字体,大小,样式)元组参数格式,一个 Lable 只能设置一种字体 |
fg | 设置 Label 的前景色 |
height/width | 设置 Lable 的高度/宽度,如果 Lable 显示的是文本,那么单位是文本单元,如果 Label 显示的是图像,那么单位就是像素,如果不设置,Label 会自动根据内容来计算出标签的高度 |
highlightbackground | 当 Label 没有获得焦点的时候高亮边框的颜色,系统的默认是标准背景色 |
highlightcolor | 指定当 Lable 获得焦点的话时候高亮边框的颜色,系统默认为0,不带高亮边框 |
image | 指定 Label 显示的图片,一般是 PhotoImage、BitmapImage 的对象 |
justify | 表示多行文本的对齐方式,参数值为 left、right、center,注意文本的位置取决于 anchor 选项 |
padx/pady | padx 指定 Label 水平方向上的间距(即内容和边框间),pady 指定 Lable 水平方向上的间距(内容和边框间的距离) |
relief | 指定边框样式,默认值是 "flat",其他参数值有 "groove"、"raised"、"ridge"、"solid"或者"sunken" |
state | 该参数用来指定 Lable 的状态,默认值为"normal"(正常状态),其他可选参数值有"active"和"disabled" |
takefocus | 默认值为False,如果是 True,表示该标签接受输入焦点 |
text | 用来指定 Lable 显示的文本,注意文本内可以包含换行符 |
underline | 给指定的字符添加下划线,默认值为 -1 表示不添加,当设置为 1 时,表示给第二个文本字符添加下划线。 |
wraplength | 将 Label 显示的文本分行,该参数指定了分行后每一行的长度,默认值为 0 |
Label控件构成
一个控件主要由背景和前景两部分组成。其中背景由三部分构成分别是内容区域、填充区、边框,这三个区域的大小通过以下属性进行控制,如下所示:
- width/height
- padx/pady
- borderwidth
下面通过一个示意图对 Label 背景的区域构成进行说明:
图1:Label控件组成
边框的宽度可以通过 borderwidth 来调整,其样式可以通过relief
来设置(默认为平的 flat);填充区的大小调整分为水平方向和垂直方向,可以使用padx
和pady
来调整;内容区则主要用来显示文字或者图片,其大小由 width/height 来控制。
# 第六章节:Tkinter Label标签
import tkinter as tk
window = tk.Tk()
# 设置窗口大小变量
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)
window.geometry(size_geo)
# 若内容是文字则以字符为单位,图像则以像素为单位
label = tk.Label(window, text="Tkinter Label标签", bg="red",
# 设置标签内容区大小
width=30, height=5,
# 设置填充区距离、边框宽度和其样式(凹陷式)
padx=10, pady=15, borderwidth=10, relief="sunken")
label.pack()
window.mainloop()
# 第六章节:Tkinter Label标签:label 设置背景图片
import tkinter as tk
window = tk.Tk()
# 设置窗口大小变量
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)
window.geometry(size_geo)
# 若内容是文字则以字符为单位,图像则以像素为单位
label = tk.Label(window, text="Tkinter Label标签", bg="red",
# 设置标签内容区大小
width=30, height=5,
# 设置填充区距离、边框宽度和其样式(凹陷式)
padx=10, pady=15, borderwidth=10, relief="sunken")
label.pack()
# 显示图片
photo = tk.PhotoImage(file='img/1.png')
tk.Label(window, image=photo).pack()
window.mainloop()
Message控件
Message 控件与 Label 控件的功能类似,它主要用来显示多行不可编辑的文本信息,与 Label 的不同之处在于该控件增加了自动换行的功能。
# 第八章节:Tkinter Message标签
import tkinter as tk
window = tk.Tk()
# 设置窗口大小变量
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)
window.geometry(size_geo)
# 若内容是文字则以字符为单位,图像则以像素为单位
txt = "鹅,鹅,鹅,曲项向天歌。白毛浮绿水,红掌拨清波"
msg = tk.Message(window, text=txt, width=60, font=('微软雅黑', 10, 'bold'))
msg .pack()
window.mainloop()
Tkinter Button 按钮控件
Button 控件是 Tkinter 中常用的窗口部件之一,同时也是实现程序与用户交互的主要控件。通过用户点击按钮的行为来执行回调函数,是 Button 控件的主要功用。首先自定义一个函数或者方法,然后将函数与按钮关联起来,最后,当用户按下这个按钮时,Tkinter 就会自动调用相关函数。
温馨提示:按钮控件使用起来非常简单,它同样可以包含文本、图像、位图,并通过command
参数回调函数。当然按钮也并非一定要执行回调函数(callback function),它也只可以当一个"摆设",不过这样的按钮是没有"灵魂的"。
# 第九章节:Tkinter Button按钮标签:点击关闭按钮,实现窗口关闭
import tkinter as tk
window = tk.Tk()
# 设置窗口大小变量
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)
window.geometry(size_geo)
# 设置回调函数
def callback():
window.destroy()
# 使用按钮控件调用函数
tk.Button(window, text="关闭按钮", command=callback).pack()
window.mainloop()
Button 控件的常营属性如下所示:
属性 | 说明 |
---|---|
anchor | 控制文本所在的位置,默认为中心位置(CENTER) |
activebackground | 当鼠标放在按钮上时候,按妞的背景颜色 |
activeforeground | 当鼠标放在按钮上时候,按钮的前景色 |
bd | 按钮边框的大小,默认为 2 个像素 |
bg | 按钮的背景色 |
command | 用来执行按钮关联的回调函数。当按钮被点击时,执行该函数 |
fg | 按钮的前景色 |
font | 按钮文本的字体样样式 |
height | 按钮的高度 |
highlightcolor | 按钮控件高亮处要显示的颜色 |
image | 按钮上要显示的图片 |
justify | 按钮显示多行文本时,用来指定文本的对齐方式,参数值有 LEFT/RIGHT/CENTER |
padx/pady | padx 指定 x 轴(水平方向)的间距大小,pady 则表示 y轴(垂直方向)的间距大小 |
ipadx/ipady | ipadx 指标签文字与标签容器之间的横向距离;ipady 则表示标签文字与标签容器之间的纵向距离 |
state | 设置按钮的可用状态,可选参数有NORMAL/ACTIVE/DISABLED,默认为 NORMAL |
text | 按钮控件要显示的文本 |
拓展:按钮布局
按钮在主窗口中的布局,通常使用 grid() 函数来完成,该函数以网格状的形式(即行和列)来管理窗口的布局。
grid() 布局管理器提供了一个sticky
参数,通过该参数可以设置按钮的方位,该参数默认将控件设置居中,其他参数值有 N/S/W/E(上/下/左/右),而且可以组合在一起使用,比如 NW/WE/SE/SW/NE 等,这与anchor
参数控制文本的显示位置,有着异曲同工之妙。如下图所示:
# 第九章节:Tkinter Button按钮标签:基于grid网格布局,实现高仿计算器
import tkinter as tk
from tkinter import NSEW
root = tk.Tk()
root.geometry("200x240+200+300")
root.title("计算器界面设计")
frame = tk.Frame(root)
frame.pack()
ent = tk.Entry(frame)
ent.grid(row=0, column=0, columnspan=4, pady=10) # columnspan跨列
btnText = (('MC', 'M+', 'M-', 'MR'),
('C', '±', '➗', '✖'),
(7, 8, 9, '-'),
(4, 5, 6, '+'),
(1, 2, 3, '='),
(0, '.'))
for rindex, r in enumerate(btnText):
for cindex, c in enumerate(r):
if c == '=':
tk.Button(frame, text=c, width=2).grid(row=rindex + 1, column=cindex, sticky=NSEW, rowspan=2)
elif c == 0:
tk.Button(frame, text=c, width=2).grid(row=rindex + 1, column=cindex, sticky=NSEW, columnspan=2)
elif c == '.':
tk.Button(frame, text=c, width=2).grid(row=rindex + 1, column=cindex + 1, sticky=NSEW)
else:
tk.Button(frame, text=c, width=2).grid(row=rindex + 1, column=cindex, sticky=NSEW)
root.mainloop()
Tkinter Entry输入控件
Entry 控件是 Tkinter GUI 编程中的基础控件之一,它的作用就是允许用户输入内容,从而实现 GUI 程序与用户的交互,比如当用户登录软件时,输入用户名和密码,此时就需要使用 Entry 控件。
基本语法格式如下:
tk_entry = Entry( master, option, ... )
基本属性
Entry 控件除了具备一些共有属性之外,还有一些自身的特殊属性,如下表所示:
属性名称 | 说明 |
---|---|
exportselection | 默认情况下,如果在输入框中选中文本会复制到粘贴板,如果要忽略这个功能,可以设置为 exportselection=0 |
selectbackground | 选中文字时的背景颜色 |
selectforeground | 选中文字时的前景色 |
show | 指定文本框内容以何种样式的字符显示,比如密码可以将值设为 show="*" |
textvariable | 输入框内值,也称动态字符串,使用 StringVar() 对象来设置,而 text 为静态字符串对象 |
xscrollcommand | 设置输入框内容滚动条,当输入的内容大于输入框的宽度时使用户 |
动态数据类型
现状:在界面编程的过程中,有时我们需要"动态跟踪"一些变量值的变化,从而保证值的变换及时的反映到显示界面上,但是 Python 内置的数据类型是无法这一目的的,因此使用了 Tkinter内置的对象,我们把这些方法创建的数据类型称为"动态类型"。支持类型:StringVar()、 BooleanVar()、DoubleVar()、IntVar()
下面通过时钟案例,加深对"动态数据类型" 理解。
# 第十一章节:Tkinter:时钟功能
import tkinter as tk
import time
root = tk.Tk()
root.title("时钟")
root.geometry('450x150+100+100')
root.resizable(0, 0)
# 获取时间的函数
def gettime():
# 获取当前时间
dstr.set(time.strftime("%H:%M:%S"))
# 每隔 1s 调用一次 gettime()函数来获取时间
root.after(1000, gettime)
# 生成动态字符串
dstr = tk.StringVar()
# 利用 textvariable 来实现文本变化
lb = tk.Label(root, textvariable=dstr, fg='green', font=("微软雅黑", 85))
lb.pack()
# 调用生成时间的函数
gettime()
# 显示窗口
root.mainloop()
常用方法
除了一些基本的属性之外,Entry 控件还提供了一些常用的方法,如下所示:
方法 | 说明 |
---|---|
delete() | 根据索引值删除输入框内的值 |
get() | 获取输入框内的是 |
set() | 设置输入框内的值 |
insert() | 在指定的位置插入字符串 |
index() | 返回指定的索引值 |
select_clear() | 取消选中状态 |
select_adujst() | 确保输入框中选中的范围包含 index 参数所指定的字符,选中指定索引和光标所在位置之前的字符 |
select_from (index) | 设置一个新的选中范围,通过索引值 index 来设置 |
select_present() | 返回输入框是否有处于选中状态的文本,如果有则返回 true,否则返回 false。 |
select_to() | 选中指定索引与光标之间的所有值 |
select_range() | 选中指定索引与光标之间的所有值,参数值为 start,end,要求 start 必须小于 end。 |
温馨提示:在 Entry 控件中,我们可以通过以下方式来指定字符的所在位置:
-
数字索引:表示从 0 开始的索引数字;
-
"ANCHOE":在存在字符的情况下,它对应第一个被选中的字符;
-
"END":对应已存在文本中的最后一个位置;
-
"insert(index,'字符'):将字符插入到 index 指定的索引位置。
第十二章节:Tkinter Entry:常用方法
import tkinter as tk
root = tk.Tk()
root.title("Tkinter Entry常用方法")
root.geometry('450x150+100+100')
root.resizable(0, 0)创建输入框控件
entry = tk.Entry(root)
放置输入框,并设置位置
entry.pack(padx=20, pady=20)
文本清空
entry.delete(0, "end")
默认文本
entry.insert(0, 'Tkinter Entry常用方法详解')
获取输入框字符串
print(entry.get())
文本清空
entry.delete(0, "end")
显示窗口
root.mainloop()
Entry控件验证功能
Entry 控件也提供了对输入内容的验证功能,比如要求输入英文字母,你却输入了数字,这就属于非法输入,Entry 控件通过以下参数实现对内容的校验:
参数 | 说明 |
---|---|
validate | 指定验证方式,字符串参数,参数值有 focus、focusin、focusout、key、all、none。 |
validatecommand | 指定用户自定义的验证函数,该函数只能返回 True 或者 Fasle |
invalidcommand | 当 validatecommand 指定的验证函数返回 False 时,可以使用该参数值再指定一个验证函数。 |
下面对 validate 的参数值做简单的介绍:
参数值 | 说明 |
---|---|
focus | 当 Entry 组件获得或失去焦点的时候验证 |
focusin | 当 Entry 组件获得焦点的时候验证 |
focuson | 当 Entry 组件失去焦点的时候验证 |
key | 当输入框被编辑的时候验证 |
all | 当出现上边任何一种情况的时候验证 |
none | 默认不启用验证功能,需要注意的是这里是字符串的 'none' |
# 第十二章节:Tkinter Entry:数据校验
import tkinter as tk
from tkinter import messagebox
root = tk.Tk()
root.title("Tkinter Entry常用方法")
root.geometry('450x150+100+100')
root.resizable(0, 0)
# 创建验证函数
def check():
if entry.get() == "abc123":
messagebox.showinfo("输入正确")
return True
else:
messagebox.showwarning("输入不正确")
entry.delete(0, tk.END)
return False
# 创建动字符串
dy_String = tk.StringVar()
# 创建输入框控件
entry = tk.Entry(root, textvariable=dy_String, validate="focusout", validatecommand=check)
# 放置输入框,并设置位置
entry.pack(padx=20, pady=20)
# 显示窗口
root.mainloop()
Tkinter 还为验证函数提供可一些额外的选项,不过想要使用这些额外选项,需要提前使用 register() 方法对验证函数进行注册,。常用的选项如下所示:
选项 | 说明 |
---|---|
%d | 有 3 个参数值,其中 0 表示删除操作;1 表示插入操作;2 表示获得、失去焦点或 textvariable 变量的值被修改导 |
%i | 当用户进行插入或者删除操作的时,该选项不爱哦是插入或者删除的索引位置,若是其他的情况则选项值为 -1 |
%P | 该选项值指定了输入框内的文本内容,只有当输入框的值允许改变的时候,该选项值才会生效。 |
%s | 改值为调用验证函数钱输入框内的文本内容 |
%S | 该选项值,只有插入或者删除操作触发验证函数的时候才会生效,它表示了被删除或者插入的内容 |
%v | 表示当前 Entry 控件的 validate 参数的值 |
%V | 表示触发验证函数的原因,值为 focus、focusin 、focusout、all、key.. 中的一个。 |
%W | 该选项表示控件类型,即控件的名字(Entry) |
# 第十四章节:Tkinter Entry:使用register() 实现数据校验
import tkinter as tk
from tkinter import messagebox
root = tk.Tk()
root.title("Tkinter Entry常用方法")
root.geometry('450x150+100+100')
root.resizable(0, 0)
# 创建验证函数
def check(strings, reason, id):
if entry.get() == "abc123":
messagebox.showinfo("输入正确")
print(strings, reason, id)
return True
else:
messagebox.showwarning("输入不正确")
entry.delete(0, tk.END)
print(strings, reason, id)
return False
# 对验证函数进行注册
checkTest = root.register(check)
# 创建动字符串
dy_String = tk.StringVar()
# 创建输入框控件
entry = tk.Entry(root, textvariable=dy_String, validate="focusout", validatecommand=(checkTest, '%P', '%V', '%W'))
# 放置输入框,并设置位置
entry.pack(padx=20, pady=20)
# 显示窗口
root.mainloop()
Spinbox 高级输入框
Spinbox 是 Entry 控件的升级版,它是 Tkinter 8.4 版本后新增的控件,该控件不仅允许用户直接输入内容,还支持用户使用微调选择器(即上下按钮调节器)来输入内容。在一般情况下,Spinbox 控件用于在固定的范围内选取一个值的时候使用。
# 第十五章节:Tkinter Spinbox:
import tkinter as tk
from tkinter import messagebox
root = tk.Tk()
root.title("Tkinter Spinbox")
root.geometry('450x150+100+100')
root.resizable(0, 0)
# 如果是数字使用 from_和to参数,范围 0-20,并且与2步长递增或递减
w = tk.Spinbox(root, from_=0, to=20, increment=2, width=15, bg='#9BCD9B')
w.pack()
# 显示窗口
root.mainloop()
若不是数字,而是字符串形式的选项值,则采用values
参数以元组的形式进行传参,如下所示:
# 使用 values 参数以元组的形式进行传参
strings = tk.Spinbox(root,values=('Python','java','C语言','PHP'))
strings.pack()
Tkinter Text文本框控件
Text 文本控件是 Tkinter 中经常使用的控件,与 Entry 控件相比,Text 控件用于显示和编辑多行文本 ,而 Entry 控件则适合处理单行文本。
Text 控件的有很多的适用场景,比如显示某个产品的详细信息,或者人物介绍等。下面我们对 Text 控件属性和常用方法做简单的介绍。
基本属性
除了基本的共有属性之外,Text 控件还具备以下属性:
属性 | 说明 |
---|---|
autoseparators | 默认为 True,表示执行撤销操作时是否自动插入一个"分隔符"(其作用是用于分隔操作记录) |
exportselection | 默认值为 True,表示被选中的文本是否可以被复制到剪切板,若是 False 则表示不允许。 |
insertbackground | 设置插入光标的颜色,默认为 BLACK |
insertborderwidth | 设置插入光标的边框宽度,默认值为 0 |
insertofftime | 该选项控制光标的闪烁频频率(灭的状态) |
insertontime | 该选项控制光标的闪烁频频率(亮的状态) |
selectbackground | 指定被选中文本的背景颜色,默认由系统决定 |
selectborderwidth | 指定被选中文本的背景颜色,默认值是0 |
selectforeground | 指定被选中文本的字体颜色,默认值由系统指定 |
setgrid | 默认值是 False,指定一个布尔类型的值,确定是否启用网格控制 |
spacing1 | 指定 Text 控件文本块中每一行与上方的空白间隔,注意忽略自动换行,且默认值为 0。 |
spacing2 | 指定 Text 控件文本块中自动换行的各行间的空白间隔,忽略换行符,默认值为0 |
spacing3 | 指定 Text 组件文本中每一行与下方的空白间隔,忽略自动换行,默认值是 0 |
tabs | 定制 Tag 所描述的文本块中 Tab 按键的功能,默认被定义为 8 个字符宽度,比如 tabs=('1c', '2c', '8c') 表示前 3 个 Tab 宽度分别为 1厘米,2厘米,8厘米。 |
undo | 该参数默认为 False,表示关闭 Text 控件的"撤销"功能,若为 True 则表示开启 |
wrap | 该参数用来设置当一行文本的长度超过 width 选项设置的宽度时,是否自动换行,参数值 none(不自动换行)、char(按字符自动换行)、word(按单词自动换行) |
xscrollcommand | 该参数与 Scrollbar 相关联,表示沿水平方向上下滑动 |
yscrollcommand | 该参数与 Scrollbar 相关联,表示沿垂直方向左右滑动 |
基本方法
Text 中的方法有几十个之多,这里不进行一一列举,主要对常用的方法进行介绍,如下表所示:
方法 | 说明 |
---|---|
bbox(index) | 返回指定索引的字符的边界框,返回值是一个 4 元组,格式为(x,y,width,height) |
edit_modified() | 该方法用于查询和设置 modified 标志(该标标志用于追踪 Text 组件的内容是否发生变化) |
edit_redo() | "恢复"上一次的"撤销"操作,如果设置 undo 选项为 False,则该方法无效。 |
edit_separator() | 插入一个"分隔符"到存放操作记录的栈中,用于表示已经完成一次完整的操作,如果设置 undo 选项为 False,则该方法无效。 |
get(index1, index2) | 返回特定位置的字符,或者一个范围内的文字。 |
image_cget(index, option) | 返回 index 参数指定的嵌入 image 对象的 option 选项的值,如果给定的位置没有嵌入 image 对象,则抛出 TclError 异常 |
image_create() | 在 index 参数指定的位置嵌入一个 image 对象,该 image 对象必须是 Tkinter 的 PhotoImage 或 BitmapImage 实例。 |
insert(index, text) | 在 index 参数指定的位置插入字符串,第一个参数也可以设置为 INSERT,表示在光标处插入,END 表示在末尾处插入。 |
delete(startindex [, endindex]) | 删除特定位置的字符,或者一个范围内的文字。 |
see(index) | 如果指定索引位置的文字是可见的,则返回 True,否则返回 False。 |
# 第十七章节:Tkinter Text:
import tkinter as tk
from tkinter import messagebox, INSERT
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x150+100+100')
root.resizable(0, 0)
# 创建一个文本控件
# width 一行可见的字符数;height 显示的行数
text = tk.Text(root, width=50, height=30, undo=True, autoseparators=False)
# 适用 pack(fill=X) 可以设置文本域的填充模式。比如 X表示沿水平方向填充,Y表示沿垂直方向填充,BOTH表示沿水平、垂直方向填充
text.pack()
# INSERT 光标处插入;END 末尾处插入
text.insert(INSERT, 'Tkinter Text 简单实例')
# 显示窗口
root.mainloop()
Text 控件通过 heigt 和 width 参数来控制文本域的大小(即纸张大小),当然您也可以将其设置为自适用模式,即不设置具体的文本域大小。
下面的示例:为上一个示例,增加"撤销"和"恢复"的功能。
# 第十七章节:Tkinter Text:
import tkinter as tk
from tkinter import messagebox, INSERT
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('400x300')
# 创建一个文本控件
# width 一行可见的字符数;height 显示的行数
text = tk.Text(root, width=50, height=3, undo=True, autoseparators=False)
# 适用 pack(fill=X) 可以设置文本域的填充模式。比如 X表示沿水平方向填充,Y表示沿垂直方向填充,BOTH表示沿水平、垂直方向填充
text.grid()
# INSERT 光标处插入;END 末尾处插入
text.insert(INSERT, 'Tkinter Text 简单实例')
# 定义撤销和恢复方法,调用edit_undo()和 edit_redo()方法
def backout():
text.edit_undo()
def regain():
text.edit_redo()
# 定义撤销和恢复按钮
tk.Button(root, text='撤销', command=backout).grid(row=3, column=0, sticky="w", padx=10, pady=5)
tk.Button(root, text='恢复', command=regain).grid(row=3, column=0, sticky="e", padx=10, pady=5)
# 显示窗口
root.mainloop()
文本控件(Text)支持三种类型的特殊结构,即 Mark、Tag 以及 Index,每一种结构都有相应的方法,下面对这些结构做相关的介绍。
Index文本索引
Index 索引,用于指定字符在文本中的真实位置,这与我们经常使用 Python 索引是一样的,不过在 Text 文本控件中,两者之间的使用形式存在一些差异。
Tkinter 提供以下文本索引类型,如下表所示:
索引类型 | 说明 |
---|---|
INSERT | 对应插入光标的位置 |
CURRENT | 对应与鼠标坐标最接近的位置 |
END | 对应 Text 控件的文本域中最后一个字符的下一个位置 |
"line.column" | 表示某一行某一列的一个位置,比如 1.2 表示第一行第二列的一个位置 |
"line.end" | 表示某一行到末尾的最后一个位置 |
SEL | 一种针对于 Tag 的特殊索引用法,(SEL_FIRST,SEL_LAST) 表示当前被选中的范围 |
# 第十七章节:Tkinter Text:
import tkinter as tk
from tkinter import messagebox, INSERT
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x150+100+100')
root.resizable(0, 0)
# 创建一个文本控件
# width 一行可见的字符数;height 显示的行数
text = tk.Text(root, width=50, height=30, undo=True, autoseparators=False)
# 适用 pack(fill=X) 可以设置文本域的填充模式。比如 X表示沿水平方向填充,Y表示沿垂直方向填充,BOTH表示沿水平、垂直方向填充
text.pack()
# INSERT 光标处插入;END 末尾处插入
text.insert(INSERT, 'Tkinter Text 简单实例')
# 显示窗口
root.mainloop()
Tag文本标签
Tag(标签)用来给一定范围内的文字起一个标签名,通过该标签名就能操控某一范围内的文字,比如修改文本的字体、尺寸和颜色。除此之外,该标签还可以和事件函数绑定在一起使用。
这里需要注意,Tags 的名字是由字符串组成的,但不能是空白字符串。
Tag 提供了一些常用的方法,通过这些方法可以操作 Tag(标签),常用方法如下:
方法 | 说明 |
---|---|
tag_add(tagName,index1,index2) | 为指定索引范围内的内容添加一个标签名字,如果 index2 不存在,则单独为 Index1 指定的内容添加 Tag |
tag_bind(tagName, sequence, func, add=None) | 为 Tag 绑定事件,解除绑定使用 tag_unbind() 方法 |
tag_cget(tagName,option) | 返回 tagName 指定的 option 选项的值 |
tag_configure(tagName, cnf=None, **kw) | 设置 tagName 的选项 |
tag_delete(tagNames) | 删除单个或者多个 tagNames 指定的标签 |
tag_lower(tagName, belowThis=None) | 降低 Tag 的优先级,如果 belowThis 参数不为空,则表示 tagName 需要比 belowThis 指定的 Tag 优先级更低 |
tag_names(index=None) | 如果不带参数,表示返回 Text 组件中所有 Tags 的名字,若存在 index 参数则返回该位置上所有 Tags 的名字 |
tag_nextrange(tagName, index1, index2=None) | 在 index1 到 index2 的范围内第一个 tagName 的位置,若不存在则返回空字符串。 |
tag_raise(tagName, aboveThis=None) | 提高 Tag 的优先级,如果 aboveThis 参数不为空,则表示 tagName 需要比 aboveThis 指定的 Tag 优先级更高 |
tag_ranges(tagName) | 返回所有 tagName 指定的文本,并将它们的范围以列表的形式返回 |
tag_remove(tagName, index1, index2=None) | 删除 index1 到 index2 之间所有的 tagName,如果忽略 index2 参数,那么只删除 index1 指定字符的 tagName |
# 第十七章节:Tkinter Text: Tag标签
import tkinter as tk
from tkinter import messagebox, INSERT, END
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x150+100+100')
root.resizable(0, 0)
# 创建一个文本控件
# width 一行可见的字符数;height 显示的行数
text = tk.Text(root, width=50, height=30, undo=True, autoseparators=False)
# 适用 pack(fill=X) 可以设置文本域的填充模式。比如 X表示沿水平方向填充,Y表示沿垂直方向填充,BOTH表示沿水平、垂直方向填充
text.pack()
# INSERT 光标处插入;END 末尾处插入
text.insert(INSERT, 'Tkinter Text 简单实例')
# 在Text控件内插入- -个按钮
button = tk.Button(text, text="关闭", command=root.quit)
text. window_create(END, window=button)
# 在第一行文字的第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")
# 显示窗口
root.mainloop()
Mark文本标记
Mark(标记)通常被用来当作书签,它可以帮助用户快速找到内容的指定位置,并且跟随相应的字符一起移动。
Mark 有两种类型的标记,分别是"INSERT"和"CURRENT",其含义如下:
- INSERT:指定当前插入光标的位置,Tkinter 会在该位置绘制一个闪烁的光标;
- CURRENT:用于指定当前光标所处坐标最邻近的位置。
它们是 Tkinter 中预定义的标记,因此不能被删除。除此上述标记外,我们还可以通过 user-define marks(用户自定义标记) 的方式来自定义 Mark。Tkinter 也提供了一些有关 Mark 的常用的方法,如下所示:
方法 | 说明 |
---|---|
mark_gravity(markName, direction=None) | 设置 Mark 的移动方向,默认是 "right",也可以设置为 "left" ,表示即如果在 Mark 处插入文本的话,Mark 的标记移动方向,也就是文本的插入方向。 |
mark_names() | 返回 Text 组件中所有 Marks 的名字 |
mark_next(index) | 返回在 index 指定的位置后边的一个 Mark 的名字 |
mark_previous(index) | 返回在 index 指定的位置前边的一个 Mark 的名字 |
mark_set(markName, index) | 移动 Mark 到 index 参数指定的位置,如果 markName 参数指定的 Mark 不存在,则创建一个新的 Mark |
mark_unset(MarkName) | 删除指定的 Mark |
注意:如果在 Mark 标记的位置之前插入或删除文本,那么 Mark 跟着一起移动。如果要删除 Mark 需要使用 mark_unset() 方法,但是只会删除 Mark 周围的文本,并不会删除 Mark 标记本身。
# 第十七章节:Tkinter Text: Mark标签
import tkinter as tk
from tkinter import messagebox, INSERT, END
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x150+100+100')
root.resizable(0, 0)
# 创建一个文本控件
# width 一行可见的字符数;height 显示的行数
text = tk.Text(root, width=50, height=30, undo=True, autoseparators=False)
# 适用 pack(fill=X) 可以设置文本域的填充模式。比如 X表示沿水平方向填充,Y表示沿垂直方向填充,BOTH表示沿水平、垂直方向填充
text.pack()
# INSERT 光标处插入;END 末尾处插入
text.insert(INSERT, 'Tkinter Text 简单实例')
# 在Text控件内插入- -个按钮
button = tk.Button(text, text="关闭", command=root.quit)
text. window_create(END, window=button)
# 在第一行文字的第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")
# 设置标记,这里的 1.end 表示 第一行最后一个字符,当然也可以使用数字来表示比如 1.5 表示第一行第五个字符
text.mark_set("name", "1.end")
# 在标记之后插入相应的文字
text.insert("name", ",Mark 标签")
# 跟着自动移动,往后插入,而不是停留在原位置
text.insert("name", ",欢迎光临")
# 若使用 mark_unset() 可以删除指定的标记
# text.mark_unset("name")
# 但使用delete来清楚所有的内容, mark 标记依旧会存在
# text.delete("1.0","end")
# 依然可以使用 name标记来插入
# text.insert("name", "Python3.0")
# 显示窗口
root.mainloop()
Tkinter列表框和组合框控件详解
列表框(Listbox)和复选框(Combobox)是 Tkinter 中两个控件,由于其非常相似,本节将它们放在一起进行介绍。
Listbox控件
首先介绍一下列表框,即 Listbox。在使用 Tkinter 进行 GUI 编程的过程中,如果需要用户自己进行选择时就可以使用列表框控件。列表框中的选项可以是多个条目,也可以是单个唯一条目,但常用于多个条目。
列表框控件(Listbox)常用方法介绍:
方法 | 说明 |
---|---|
activate(index) | 将给定索引号对应的选项激活,即文本下方画一条下划线 |
bbox(index) | 返回给定索引号对应的选项的边框,返回值是一个以像素为单位的 4 元祖表示边框:(xoffset, yoffset, width, height), xoffset 和 yoffset 表示距离左上角的偏移位置 |
curselection() | 返回一个元组,包含被选中的选项序号(从 0 开始) |
delete(first, last=None) | 删除参数 first 到 last 范围内(包含 first 和 last)的所有选项 |
get(first, last=None) | 返回一个元组,包含参数 first 到 last 范围内(包含 first 和 last)的所有选项的文本 |
index(index) | 返回与 index 参数相应选项的序号 |
itemcget(index, option) | 获得 index 参数指定的项目对应的选项(由 option 参数指定) |
itemconfig(index, **options) | 设置 index 参数指定的项目对应的选项(由可变参数 **option 指定) |
nearest(y) | 返回与给定参数 y 在垂直坐标上最接近的项目的序号 |
selection_set(first, last=None) | 设置参数 first 到 last 范围内(包含 first 和 last)选项为选中状态,使用 selection_includes(序号) 可以判断选项是否被选中。 |
size() | 返回 Listbox 组件中选项的数量 |
xview(*args) | 该方法用于在水平方向上滚动 Listbox 组件的内容,一般通过绑定 Scollbar 组件的 command 选项来实现。 如果第一个参数是 "moveto",则第二个参数表示滚动到指定的位置:0.0 表示最左端,1.0 表示最右端;如果第一个参数是 "scroll",则第二个参数表示滚动的数量,第三个参数表示滚动的单位(可以是 "units" 或 "pages"),例如:xview("scroll", 2, "pages")表示向右滚动二行。 |
yview(*args) | 该方法用于在垂直方向上滚动 Listbox 组件的内容,一般通过绑定 Scollbar 组件的 command 选项来实现 |
除了共有属性之外,列表框控件也有一些其他属性,如下表所示:
属性 | 说明 |
---|---|
listvariable | 1. 指向一个 StringVar 类型的变量,该变量存放 Listbox 中所有的项目 2. 在 StringVar 类型的变量中,用空格分隔每个项目,例如 var.set("c c++ java python") |
selectbackground | 1. 指定当某个项目被选中的时候背景颜色,默认值由系统指定 |
selectborderwidth | 1. 指定当某个项目被选中的时候边框的宽度 2. 默认是由 selectbackground 指定的颜色填充,没有边框 3. 如果设置了此选项,Listbox 的每一项会相应变大,被选中项为 "raised" 样式 |
selectforeground | 1. 指定当某个项目被选中的时候文本颜色,默认值由系统指定 |
selectmode | 1. 决定选择的模式,tk 提供了四种不同的选择模式,分别是:"single"(单选)、"browse"(也是单选,但拖动鼠标或通过方向键可以直接改变选项)、"multiple"(多选)和 "extended"(也是多选,但需要同时按住 Shift 键或 Ctrl 键或拖拽鼠标实现),默认是 "browse" |
setgrid | 指定一个布尔类型的值,决定是否启用网格控制,默认值是 False |
takefocus | 指定该组件是否接受输入焦点(用户可以通过 tab 键将焦点转移上来),默认值是 True |
xscrollcommand | 为 Listbox 组件添加一条水平滚动条,将此选项与 Scrollbar 组件相关联即可 |
yscrollcommand | 为 Listbox 组件添加一条垂直滚动条,将此选项与 Scrollbar 组件相关联即可 |
# 第二十一章节:Tkinter ListBox
import tkinter as tk
from tkinter import messagebox, INSERT, END
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x150+100+100')
root.resizable(0, 0)
# 创建列表选项
listbox1 = tk.Listbox(root)
listbox1.pack()
# i表示索引值,item 表示值,根据索引值的位置依次插入
for i, item in enumerate(["C", "C++", "JavaScript", "Python", "Java", "SQL"]):
listbox1.insert(i, item)
# 显示窗口
温馨提示:除了使用 enumerate() 来实现选项插入的方法外,我们还可以使用 "end" 实现,它表示将选项插入到最后一个位置。核心代码片段:
# i表示索引值,item 表示值,根据索引值的位置依次插入
for item in ["C","C++","C#","Python","Java"]:
listbox1.insert("end",item)
为列表框控件(Listbox)增加滚动条和删除功能
# 第二十一章节:Tkinter ListBox 添加滚动条和删除功能
import tkinter as tk
from tkinter import messagebox, INSERT, END, RIGHT, Y, MULTIPLE, ACTIVE, BOTTOM
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x150+100+100')
root.resizable(0, 0)
# 创建滚动条
s = tk.Scrollbar(root)
# 设置垂直滚动条显示的位置,使得滚动条,靠右侧;通过 fill 沿着 Y 轴填充
s.pack(side=RIGHT, fill=Y)
# 创建列表选项,将selectmode设置为多选模式,并为Listbox控件添加滚动条
listbox1 = tk.Listbox(root, selectmode=MULTIPLE, height=5, yscrollcommand=s.set)
listbox1.pack()
# i表示索引值,item 表示值,根据索引值的位置依次插入
for i, item in enumerate(["C", "C++", "JavaScript", "Python", "Java", "SQL"]):
listbox1.insert(i, item)
# 设置滚动条,使用 yview使其在垂直方向上滚动 Listbox 组件的内容,通过绑定 Scollbar 组件的 command 参数实现
s.config(command=listbox1.yview)
# 使用匿名函数,创建删除函数,点击删除按钮,会删除选项
bt = tk.Button(root, text='删除', command=lambda x=listbox1:x.delete(ACTIVE))
# 将按钮放置在底部
bt.pack(side=BOTTOM)
# 显示窗口
root.mainloop()
StringVar() 动态获取列表选项
如何通过 StringVar() 方法动态地获取列表框中的选中项,示例代码如下:
# 第二十一章节:Tkinter ListBox 获取列表项选择值
import tkinter as tk
from tkinter import messagebox, INSERT, END, RIGHT, Y, MULTIPLE, ACTIVE, BOTTOM
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x150+100+100')
root.resizable(0, 0)
# 创建变量,用var1用来接收鼠标点击的具体选项内容
var1 = tk.StringVar()
l = tk.Label(root, bg='#B0B0B0', font=('微软雅黑', 15), width=20, textvariable=var1)
l.pack()
# 创建一个按钮的点击事件
def click_button():
# 使用 curselection来选中文本
try:
val = listbox1.get(listbox1.curselection())
# 设置label值
var1.set(val)
except Exception as e:
e = '发现一个错误'
messagebox.showwarning(e, '没有选择任何条目')
# 创建一个按钮并放置,点击按钮调用print_selection函数
b1 = tk.Button(root, text='获取当前选项', command=click_button)
b1.pack()
# 创建Listbox并为其添加内容
var2 = tk.StringVar()
var2.set(("C语言辅导班", "Python答疑辅导", "Java答疑辅导", "C++辅导"))
s = tk.Scrollbar(root)
# 设置垂直滚动条显示的位置,使得滚动条,靠右侧;通过 fill 沿着 Y 轴填充
s.pack(side=RIGHT, fill=Y)
# 创建列表选项,将selectmode设置为多选模式,并为Listbox控件添加滚动条
listbox1 = tk.Listbox(root, selectmode=MULTIPLE, height=5, yscrollcommand=s.set, listvariable=var2)
listbox1.pack()
# i表示索引值,item 表示值,根据索引值的位置依次插入
for i, item in enumerate(["C", "C++", "JavaScript", "Python", "Java", "SQL"]):
listbox1.insert(i, item)
# 设置滚动条,使用 yview使其在垂直方向上滚动 Listbox 组件的内容,通过绑定 Scollbar 组件的 command 参数实现
s.config(command=listbox1.yview)
# 使用匿名函数,创建删除函数,点击删除按钮,会删除选项
bt = tk.Button(root, text='删除', command=lambda x=listbox1:x.delete(ACTIVE))
# 将按钮放置在底部
bt.pack(side=BOTTOM)
# 显示窗口
root.mainloop()
Combobox控件
Combobox,是一个组合框控件,它是 Entry 控件和 Listbox 控件的组合,用户可以从下拉列表中选择一项,也可以手动输入。
其语法格式如下所示:
cbox=Combobox(窗口对象,[参数列表])
对于 Combobox 控件而言,它常用的方法有两个,分别是 get() 和 current(),前者表示获取当前选中选项的内容,后者表示获取选中选项的索引值。下面通过一组简单的示例进一步了解 Combobox 控件,示例代码如下:
# 第二十一章节:Tkinter ComboxBox
import tkinter as tk
from tkinter import messagebox, INSERT, END, ttk
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x150+100+100')
root.resizable(0, 0)
def callback(event):
print("选择项:", combo.get())
# 创建一个 Combobox
combo = ttk.Combobox(root)
# 设置 Combobox 的选项
combo['values'] = ("选项 A", "选项 B", "选项 C")
# 设置默认选择的项
combo.current(0)
# 为选项选择设置一个回调函数
combo.bind("<<ComboboxSelected>>", callback)
combo.pack()
# 显示窗口
root.mainloop()
Tkinter单选框和多选框按钮
单选框按钮控件(Radiobutton),同样允许用户选择具体的选项值,不过与 Listbox 相比,单选按钮控件仅允许用户选择单一的选项值,各个选项值之间是互斥的关系,因此只有一个选项可以被用户选择。
Radiobutton 控件通常都是成组出现的,所有控件都使用相同的变量。Radiobutton 可以包含文本或图像,每一个按钮都可以与一个 Python 函数相关联。当按钮被按下时,对应的函数会被执行。这里需要注意的是,单选按钮控件仅能显示单一字体的文本,但文本可以跨越多行,除此之外,您还可以为个别的字符添加下划线。
Radiobutton 除常用的共有属性之外,还具有一些其他属性,如下表所示:
属性 | 说明 |
---|---|
activebackground | 设置当 Radiobutton 处于活动状态(通过 state 选项设置状态)的背景色,默认值由系统指定 |
activeforeground | 设置当 Radiobutton 处于活动状态(通过 state 选项设置状态)的前景色,默认值由系统指定 |
compound | 1. 默认值为 None,控制 Radiobutton 中文本和图像的混合模式,默认情况下,如果有指定位图或图片,则不显示文本 2. 如果该选项设置为 "center",文本显示在图像上(文本重叠图像) 3. 设置为 "bottom","left","right" 或 "top",那么图像显示在文本的旁边,比如如"bottom",则显示图像在文本的下方。 |
disabledforeground | 指定当 Radiobutton 不可用的时的前景色颜色,默认由系统指定 |
indicatoron | 1. 该参数表示选项前面的小圆圈是否被绘制,默认为 True,即绘制; 2. 如果设置为 False,则会改变单选按钮的样式,当点击时按钮会变成 "sunken"(凹陷),再次点击变为 "raised"(凸起) |
selectcolor | 设置当 Radiobutton 为选中状态的时候显示的图片;如果没有指定 image 选项,该选项被忽略 |
takefocus | 如果是 True,该组件接受输入焦点,默认为 False |
variable | 表示与 Radiobutton 控件关联的变量,注意同一组中的所有按钮的 variable 选项应该都指向同一个变量,通过将该变量与 value 选项值对比,可以判断用户选中了哪个按钮 |
Radiobutton 控件的常用方法如下所示:
方法 | 说明 |
---|---|
deselect() | 取消该按钮的选中状态 |
flash() | 刷新 Radiobutton 控件,该方法将重绘 Radiobutton控件若干次(即在"active" 和 "normal" 状态间切换) |
invoke() | 1. 调用 Radiobutton 中 command 参数指定的函数,并返回函数的返回值 2. 如果 Radiobutton 控件的 state(状态) 是 "disabled" (不可用)或没有指定 command 选项,则该方法无效 |
select() | 将 Radiobutton 控件设置为选中状态 |
# 第二十五章节:Tkinter Radiobutton
import tkinter as tk
from tkinter import messagebox, INSERT, END, ttk
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x150+100+100')
root.resizable(0, 0)
# IntVar() 用于处理整数类型的变量
v = tk.IntVar()
# 根据单选按钮的 value 值来选择相应的选项
v.set(0)
# 使用 variable 参数来关联 IntVar() 的变量 v
tk.Radiobutton(root, text="苹果", fg='blue', font=('微软雅黑', '12', 'bold'), variable=v, value=0).pack(anchor='w')
tk.Radiobutton(root, text="香蕉", variable=v, value=2).pack(anchor='w')
tk.Radiobutton(root, text="梨", variable=v, value=3).pack(anchor='w')
tk.Radiobutton(root, text="西瓜", variable=v, value=4).pack(anchor='w')
# 显示窗口
root.mainloop()
上述代码是比较直接的写法,虽然编码过程简单,但是从代码重构的角度来讲,它是比较冗余的,因此我们推荐下面这种写法,如下所示:
# 第二十五章节:Tkinter Radiobutton 优化
import tkinter as tk
from tkinter import messagebox, INSERT, END, ttk
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x150+100+100')
root.resizable(0, 0)
site = [('Java 从入门到精通', 1),
('SQL 从入门到放弃', 2),
('JavaScrit 高手荆棘之路', 3),
('Python 项目实战', 4)]
# IntVar() 用于处理整数类型的变量
v = tk.IntVar()
# 重构后的写法,也非常简单易懂
for name, num in site:
radio_button = tk.Radiobutton(root, text=name, variable=v, value=num)
radio_button.pack(anchor='w')
# 显示窗口
root.mainloop()
再对上述代码稍作修改,当点击某一按钮时,获取选项的内容,代码如下:
# 第二十五章节:Tkinter Radiobutton 优化 + 点击事件
import tkinter as tk
from tkinter import messagebox, INSERT, END, ttk
def select():
dicts = {1: 'Java 从入门到精通', 2: 'SQL 从入门到放弃', 3: 'JavaScrit 高手荆棘之路', 4: 'Python 项目实战'}
strings = '您选择了' + dicts.get(v.get()) + ',祝您学习愉快'
lable.config(text=strings)
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x150+100+100')
root.resizable(0, 0)
lable = tk.Label(root, font=('微软雅黑', '15', 'bold'), fg='#43CD80')
lable.pack(side='bottom')
site = [('Java 从入门到精通', 1),
('SQL 从入门到放弃', 2),
('JavaScrit 高手荆棘之路', 3),
('Python 项目实战', 4)]
# IntVar() 用于处理整数类型的变量
v = tk.IntVar()
# 重构后的写法,也非常简单易懂
for name, num in site:
radio_button = tk.Radiobutton(root, text=name, variable=v, value=num, command=select, indicatoron=False)
radio_button.pack(anchor='w')
# 显示窗口
root.mainloop()
Checkbutton复选框控件
Checkbutton 控件是一种供用户选择相应条目的按钮控件,但与 Radiobutton 不同的是,Checkbutton 控件不仅允许用户选择一项,还允许用户同时选择多项,各个选项之间属于并列的关系。
复选框控件同样有许多适用场景,比如选择兴趣爱好、选择选修课,以及购买多个物品等,在这种情况下都可以使用复选框控件,其语法格式如下:
Checkbutton(master=None, **options)
复选框控件,除了具有常用的共有属性之外,还具有一些其他重要属性和常用方法,下面对它们做简单地介绍:
属性 | 说明 |
---|---|
text | 显示的文本,使用 "\n" 来对文本进行换行。 |
variable | 1. 和复选框按钮关联的变量,该变量值会随着用户选择行为来改变(选或不选),即在 onvalue 和 offvalue 设置值之间切换,这些操作由系统自动完成 2. 在默认情况下,variable 选项设置为 1 表示选中状态,反之则为 0,表示不选中。 |
onvalue | 通过设置 onvalue 的值来自定义选中状态的值。 |
offvalue | 通过设置 offvalue 的值来自定义未选中状态的值。 |
indicatoron | 默认为 True,表示是否绘制用来选择的选项的小方块,当设置为 False 时,会改变原有按钮的样式,与单选按钮相同 |
selectcolor | 选择框的颜色(即小方块的颜色),默认由系统指定 |
selectimage | 设置当 Checkbutton 为选中状态的时候显示的图片,若如果没有指定 image 选项,该选项被忽略 |
textvariable | Checkbutton 显示 Tkinter 变量(通常是一个 StringVar 变量)的内容,如果变量被修改,Checkbutton 的文本会自动更新 |
wraplength | 表示复选框文本应该被分成多少行,该选项指定每行的长度,单位是屏幕单元,默认值为 0 |
# 第二十五章节:Tkinter Checkbutton
import tkinter as tk
from tkinter import messagebox, INSERT, END, ttk, LEFT, BOTTOM, X
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x150+100+100')
root.resizable(0, 0)
# 新建整型变量
CheckVar1 = tk.IntVar()
CheckVar2 = tk.IntVar()
CheckVar3 = tk.IntVar()
# 设置三个复选框控件,使用variable参数来接收变量
check1 = tk.Checkbutton(root, text="Python", font=('微软雅黑', 15, 'bold'), variable=CheckVar1, onvalue=1, offvalue=0)
check2 = tk.Checkbutton(root, text="C语言", font=('微软雅黑', 15, 'bold'), variable=CheckVar2, onvalue=1, offvalue=0)
check3 = tk.Checkbutton(root, 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 = tk.Button(root, text="选好了", bg='#BEBEBE', command=study)
btn.pack(side=LEFT)
# 该标签,用来显示选择的文本
lb2 = tk.Label(root, text='', bg='#9BCD9B', font=('微软雅黑', 11, 'bold'), width=5, height=2)
lb2.pack(side=BOTTOM, fill=X)
# 显示窗口
root.mainloop()
复选框控件提供以下常用方法,如下表所示:
方法 | 属性 |
---|---|
desellect() | 取消 Checkbutton 组件的选中状态,也就是设置 variable 为 offvalue |
flash() | 刷新 Checkbutton 组件,对其进行重绘操作,即将前景色与背景色互换从而产生闪烁的效果。 |
invoke() | 1. 调用 Checkbutton 中 command 选项指定的函数或方法,并返回函数的返回值 2. 如果 Checkbutton 的state(状态)"disabled"是 (不可用)或没有指定 command 选项,则该方法无效 |
select() | 将 Checkbutton 组件设置为选中状态,也就是设置 variable 为 onvalue |
toggle() | 改变复选框的状态,如果复选框现在状态是 on,就改成 off,反之亦然 |
核心代码片段:
# 设置三个复选框控件,使用variable参数来接收变量
check1 = tk.Checkbutton(root, text="Python", font=('微软雅黑', 15, 'bold'), variable=CheckVar1, onvalue=1, offvalue=0)
check2 = tk.Checkbutton(root, text="C语言", font=('微软雅黑', 15, 'bold'), variable=CheckVar2, onvalue=1, offvalue=0)
check3 = tk.Checkbutton(root, 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)
Tkinter Scale控件详解
Scale 控件,即滑块控件或标尺控件,该控件可以创建一个类似于标尺式的滑动条对象,用户通过操作它可以直接设置相应的数值(刻度值)。
Scale 控件同样有许多应用场景,并且在我们日常工作中也会经常用到,比如电脑上调节音量的滑动条(数值范围 0-100)
Scale 控件常用的基本属性如下所示:
参数 | 说明 |
---|---|
activebackground | 指定当鼠标在上方飘过的时候滑块的背景颜色 |
bigincrement | 1. 设置"大"增长量 2. 该选项设置增长量的大小 3. 默认值是 0,增长量为范围的 1/10 |
borderwidth | 1. 指定边框宽度 2. 默认值是 2 |
command | 1. 指定一个函数,每当滑块发生改变的时候都会自动调用该函数 2. 该函数有一个唯一的参数,就是最新的滑块位置 3. 如果滑块快速地移动,函数可能无法获得每一个位置,但一定会获得滑块停下时的最终位置 |
digits | 1. 设置最多显示多少位数字 2. 补充注释:例如设置 from 选项为 0,to 选项为 20,digits 选项设置为 5,那么滑块的范围就是在 0.000 ~ 20.000 直接滑动 3. 默认值是 0(不开启) |
font | 1. 指定滑块左侧的 Label 和刻度的文字字体 2. 默认值由系统指定 |
from_ | 1. 设置滑块最顶(左)端的位置 2. 默认值是 0 |
highlightcolor | 1. 指定当 Scale 获得焦点的时候高亮边框的颜色 2. 默认值由系统指定 |
label | 1. 你可以在垂直的 Scale 组件的顶端右侧(水平的话是左端上方)显示一个文本标签 2. 默认值是不显示标签 |
length | 1. Scale 组件的长度,默认值是 100 像素 |
orient | 1. 设置 Scale 控件是水平放置(HORIZONTAL)还是垂直放置(VERTICAL) 2. 默认值是 VERTICAL(垂直放置) |
repeatdelay | 1. 该选项指定鼠标左键点击滚动条凹槽的响应时间 2. 默认值是 300(毫秒) |
repeatinterval | 1. 该选项指定鼠标左键紧按滚动条凹槽时的响应间隔 2. 默认值是 100(毫秒) |
resolution | 1. 指定 Scale 组件的分辨率(每点击一下移动的步长) 示例: 比如 resolution 选项设置为 0.1 的话,那么每点击一下鼠标就是在 0.0 ~ 20.0 之间以 0.1 的步长移动 2. 该参数的默认值是 1 |
showvalue | 1. 设置是否显示滑块旁边的数字 2. 默认值为 True |
sliderlength | 1. 设置滑块的长度 2. 默认值是 30 像素 |
state | 1. 默认情况下 Scale 组件支持鼠标事件和键盘事件,可以通过设置该选项为 DISABLED 来禁用此功能 2. 默认值是 NORMAL |
takefocus | 1. 指定使用 Tab 键是否可以将焦点移动到该 Scale 组件上 2. 默认是开启的,可以通过将该选项设置为 False 避免焦点落在此组件上 |
tickinterval | 1. 设置显示的刻度,如果设置一个值,那么就会按照该值的倍数显示刻度 2. 默认值是不显示刻度 |
to | 1. 设置滑块最底(右)端的位置 2. 默认值是 100 |
troughcolor | 1. 设置凹槽的颜色 2. 默认值由系统指定 |
variable | 1. 指定一个与 Scale 组件相关联的 Tkinter 变量,该变量存放滑块最新的位置 2. 当滑块移动的时候,该变量的值也会发生相应的变化 |
width | 1. 指定 Scale 组件的宽度 2. 默认值是 15 像素 |
Scale 常用方法有如下四个,见下表所示:
方法 | 说明 |
---|---|
coords(value=None) | 1. 获得当前滑块位置相对于 Scale 控件左上角位置的相对坐标, 2. 如果设置了 value 值,则返回当滑块位于该位置时与左上角的相对坐标 |
get() | 获得当前滑块的位置(即当前数值),返回值可以为整型或者浮点型 |
identify(x, y) | 返回一个字符串表示指定位置下的 Scale 控件 |
set(value) | 设置 Scale 控件的值,即滑块的位置,默认为初始位置 |
# 第二十五章节:Tkinter Scale
import tkinter as tk
from tkinter import messagebox, INSERT, END, ttk, LEFT, BOTTOM, X
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x150+100+100')
root.resizable(0, 0)
# 添加一个 Scale 控件,默认垂直方向,步长设置为 5,长度为200,滑动块的大小为 50,最后使用label参数文本
s = tk.Scale(root, from_=100, to=0, resolution=5, length=200, sliderlength=20, label='音量控制')
s.pack()
# 设置滑块的位置
s.set(value=15)
# 显示窗口
root.mainloop()
下面看一个稍微复杂点的应用示例,代码如下:
# 第二十五章节:Tkinter Scale
import tkinter as tk
from tkinter import messagebox, INSERT, END, ttk, LEFT, BOTTOM, X
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x150+100+100')
root.resizable(0, 0)
# 创建一个文本标签
label = tk.Label(root, bg='#9FB6CD', width=18, text='')
label.grid(row=2)
# 创建执行函数
def select_price(value):
label.config(text='您购买的数量是 ' + value)
# 创建 Scale控件
scale = tk.Scale(root,
label='选择您要购买的数量',
from_=1,
to=100,
orient=tk.HORIZONTAL, # 设置Scale控件平方向显示
length=400,
tickinterval=9, # 设置刻度滑动条的间隔
command=select_price) # 调用执行函数,是数值显示在 Label控件中
scale.grid(row=1)
# 显示窗口
root.mainloop()
Tkinter Menu菜单控件
Menu 控件(菜单控件)可以说是 GUI 中"精髓所在",它以可视化的方式将一系列的"功能选项卡"进行分组,并在每个分组下又"隐藏"了许多其他的"选项卡"。当打开菜单时,这些选项卡就会"显式"的呈现出来,方便用户进行选择。
通过使用菜单控件(Menu)可以充分地节省有限的窗口区域,让我们的界面更加简洁优雅,避免臃肿、混乱。
Tkinter Menu 控件提供了三种类型的菜单,分别是:topleve(主目录菜单)、pull-down(下拉式菜单)、pop-up(弹出式菜单,或称快捷式菜单)。
下表列出创建菜单时用到的相关方法,如下所示:
方法 | 说明 |
---|---|
add_cascade(**options) | 添加一个父菜单,将一个指定的子菜单,通过 menu 参数与父菜单连接,从而创建一个下拉菜单。 |
add_checkbutton(**options) | 添加一个多选按钮的菜单项 |
add_command(**options) | 添加一个普通的命令菜单项 |
add_radiobutton(**options) | 添加一个单选按钮的菜单项 |
add_separator(**options) | 添加一条分割线 |
add(add(itemType, options)) | 添加菜单项,此处 itemType 参数可以是以下几种:"command"、"cascade", "checkbutton"、"radiobutton"、"separator" 五种,并使用 options 选项来设置 菜单其他属性。 |
除了上述方法之外,Menu 控件也提供了一些其他方法来操作菜单项,比如删除菜单项、获取菜单项、设置指定的菜单项等,如下表所示:
方法 | 说明 |
---|---|
delete(index1, index2=None) | 1. 删除 index1 ~ index2(包含)的所有菜单项 2. 如果忽略 index2 参数,则删除 index1 指向的菜单项 |
entrycget(index, option) | 获得指定菜单项的某选项的值 |
entryconfig(index, **options) | 设置指定菜单项的选项 |
index(index) | 返回与 index 参数相应的选项的序号 |
insert(index, itemType, **options) | 插入指定类型的菜单项到 index 参数指定的位置,类型可以是 是:"command","cascade","checkbutton","radiobutton" 或 "separator" 中的一个,或者也可以使用 insert_类型() 形式来, 比如 insert_cascade(index, **options)..等 |
invoke(index) | 调用 index 指定的菜单项相关联的方法 |
post(x, y) | 在指定的位置显示弹出菜单 |
type(index) | 获得 index 参数指定菜单项的类型 |
unpost() | 移除弹出菜单 |
yposition(index) | 返回 index 参数指定的菜单项的垂直偏移位置 |
下面对 Menu 控件的 options 参数做简单地介绍,如下所示:
属性 | 说明 |
---|---|
accelerator | 1. 设置菜单项的快捷键,快捷键会显示在菜单项目的右边,比如 accelerator = "Ctrl+O" 表示打开; 2. 注意,此选项并不会自动将快捷键与菜单项连接在一起,必须通过按键绑定来实现 |
command | 选择菜单项时执行的 callback 函数 |
label | 定义菜单项内的文字 |
menu | 此属性与 add_cascade() 方法一起使用,用来新增菜单项的子菜单项 |
selectcolor | 指定当菜单项显示为单选按钮或多选按钮时选择中标志的颜色 |
state | 定义菜单项的状态,可以是 normal、active 或 disabled |
onvalue/offvalue | 1. 默认情况下,variable 选项设置为 1 表示选中状态,反之设置为 0,设置 offvalue/onvalue 的值可以自定义未选中状态的值 2. |
tearoff | 1. 如果此选项为 True,在菜单项的上面就会显示一个可选择的分隔线; 2. 注意:分隔线会将此菜单项分离出来成为一个新的窗口 |
underline | 设置菜单项中哪一个字符要有下画线 |
value | 1. 设置按钮菜单项的值 2. 在同一组中的所有按钮应该拥有各不相同的值 3. 通过将该值与 variable 选项的值对比,即可判断用户选中了哪个按钮 |
variable | 当菜单项是单选按钮或多选按钮时,与之关联的变量 |
1)创建主目录菜单
主目录菜单也称之为"顶级菜单",下拉菜单等其他子菜单的都需要建立在"顶级菜单"的基础之上,下面示例创建了一个类似于"记事本"界面的程序,代码如下:
# 第三十一章节:Tkinter Menu
import tkinter as tk
from tkinter import messagebox, INSERT, END, ttk, LEFT, BOTTOM, X
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x150+100+100')
root.resizable(0, 0)
# 绑定一个执行函数,当点击菜单项的时候会显示一个消息对话框
def menuCommand():
tk.messagebox.showinfo("主菜单栏", "你正在使用主菜单栏")
# 创建一个主目录菜单,也被称为顶级菜单
main_menu = tk.Menu(root)
# 新增命令菜单项,使用 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)
main_menu.add_command(label="帮助", command=menuCommand)
# 显示菜单
root.config(menu=main_menu)
# 显示窗口
root.mainloop()
2) 创建下拉菜单
下拉菜单时主菜单的重要组成部分,也是用户选择相关命令的重要交互界面,下拉菜单的创建方式也非常简单,不过需要我们注意,下拉菜单是建立的主菜单(即顶级菜单)的基础之上的,并非主窗口之上,这一点千万不要搞混,否则创建下拉菜单会失败。
下面继续仿照"记事本"的相关功能来创建下拉菜单,示例如下:
# 第三十一章节:Tkinter Menu
import tkinter as tk
from tkinter import messagebox, INSERT, END, ttk, LEFT, BOTTOM, X
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x150+100+100')
root.resizable(0, 0)
# 绑定一个执行函数,当点击菜单项的时候会显示一个消息对话框
def menuCommand():
tk.messagebox.showinfo("主菜单栏", "你正在使用主菜单栏")
# 创建一个主目录菜单,也被称为顶级菜单
main_menu = tk.Menu(root)
# 在顶级菜单上新增"文件"菜单的子菜单,同时不添加分割线
filemenu = tk.Menu(root, 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=root.quit)
# 在主目录菜单上新增"文件"选项,并通过menu参数与下拉菜单绑定
main_menu.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)
# 显示菜单
root.config(menu=main_menu)
# 显示窗口
root.mainloop()
3) 创建弹出菜单栏
弹出式菜单栏,也称为快捷式菜单栏,比如通过点击鼠标右键弹出一个菜单栏,其中包含一些常用的选项卡,如复制、粘贴等,如下所示:在记事本的空白处点击鼠标右键会弹出一个菜单栏。
# 第三十一章节:Tkinter Menu
import tkinter as tk
from tkinter import messagebox, INSERT, END, ttk, LEFT, BOTTOM, X
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x150+100+100')
root.resizable(0, 0)
def func():
print('您通过弹出菜单执行了命令')
# 创建一个弹出菜单
menu = tk.Menu(root, 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表示点击中间的滑轮
root.bind("<Button-3>", command)
# 显示窗口
root.mainloop()
4) 菜单按钮控件
Menubutton(菜单按钮控件)是一个与 Menu 控件相关联的按钮,当我们按下按钮的时候下拉菜单就会自动弹出。通过 Menubutton 创建的菜单按钮可以自由地放置在窗口中的任意位置,从而提高了 GUI 界面的灵活性。
下面看一组简单使用示例:
# 第三十一章节:Tkinter Menu
import tkinter as tk
from tkinter import messagebox, INSERT, END, ttk, LEFT, BOTTOM, X
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x150+100+100')
root.resizable(0, 0)
# 创建一个菜单按钮
menubtn = tk.Menubutton(root, text='点击进行操作', relief='sunk')
# 设置位置(布局)
menubtn.grid(padx=195, pady=105)
# 添加菜单,使用 tearoff 参数不显示分割线
filemenu = tk.Menu(menubtn, tearoff=False)
filemenu.add_command(label='新建')
filemenu.add_command(label='删除')
filemenu.add_command(label='复制')
filemenu.add_command(label='保存')
# 显示菜单,将菜单命令绑定在菜单按钮对象上
menubtn.config(menu=filemenu)
# 显示窗口
root.mainloop()
Tkinter Scrollbar滚动条控件
Scrollbar 控件常用于创建一个水平或者垂直的滚动条,通常情况下,Scrollbar 控件可以与 Listbox、Text、Canvas 以及 Entry 等控件一起使。
滚动条控件是 GUI 程序中经常使用的一种控件类型,它主要用来控制控件区域的可见范围,比如当 Text 控件的文本内容非常多时,为了方便用户阅读,可以给 Text 控件增加滚动条,用户只需拖动滚动条就能完成内容的阅读。
Scrollbar 控件的常用属性,如下表所示:
属性 | 说明 |
---|---|
activebackground | 指定当鼠标在上方飘过的时候滑块和箭头的背景颜色,默认由系统决定 |
activerelief | 指定当鼠标在滑块上方飘过时滑块的样式,默认值是 "raised",其他可选值有 "flat","sunken","groove","ridge" |
background(bg) | 指定背景颜色,默认值由系统指定 |
borderwidth(bd) | 指定边框宽度,默认值是 0 |
command | 当滚动条更新时回调的函数,通常指定对应组件的 xview() 或 yview() 方法 |
cursor | 指定当鼠标在上方飘过的时的鼠标样式,默认值由系统指定 |
elementborderwidth | 1. 指定滚动条和箭头的边框宽度 2. 默认值是 -1(表示使用 borderwidth 选项的值) |
jump | 1. 指定当用户拖拽滚动条时的行为 2. 默认值为 False,滚动条的任何一丝变动都会即刻调用 command 指定的回调函数 3. 设置为 True 则当用户松开鼠标才调用 |
orient | 指定绘制 "horizontal"(垂直滚动条)还是 "vertical"(水平滚动条),默认值是 VERTICAL |
repeatdelay | 该选项指定鼠标左键点击滚动条凹槽的响应时间,默认值是 300(毫秒) |
repeatinterval | 该选项指定鼠标左键紧按滚动条凹槽时的响应间隔,默认值是 100(毫秒) |
takefocus | 指定使用 Tab 键可以将焦点移到该 Scrollbar 组件上,默认为开启,可以将该选项设置为 False 避免焦点在此组件上 |
troughcolor | 指定凹槽的颜色,默认由系统指定 |
width | 指定滚动条的宽度,默认值是 16px |
下面是介绍了 Scrollbar 控件常用的函数:
属性 | 说明 |
---|---|
activate(element) | 1. 显示 element 参数指定的元素的背景颜色和样式; 2. element 参数可以设置为:"arrow1"(箭头1),"arrow2"(箭头2)或 "slider"(滑块) |
delta(deltax, deltay) | 1. 给定一个鼠标移动的范围 deltax 和 deltay,然后该方法返回一个浮点类型的值(范围 -1.0 ~ 1.0) 2. 注意:deltax 表示水平移动量,deltay 表示垂直移动量 |
fraction(x, y) | 给定一个像素坐标 (x, y),该方法返回最接近给定坐标的滚动条位置。 |
get() | 返回当前滑块的位置 (a, b),其中 a 值表示当前滑块的顶端或左端的位置,b 值表示当前滑块的底端或右端的位置。 |
identify(x, y) | 1. 返回一个字符串表示指定位置下(如果有的话)的滚动条部件, 2. 返回值可以是:"arrow1"(箭头1),"arrow2"(箭头2)、"slider"(滑块)或 ""(空) |
set(*args) | 1. 设置当前滚动条的位置 2. 该方法有两个参数即 (first, last),其中 first 表示当前滑块的顶端或左端的位置,last 表示当前滑块的底端或右端的位置(范围 0.0 ~ 1.0) |
滚动条示例:
# 第三十五章节:Tkinter Scrollbar
import tkinter as tk
from tkinter import messagebox, INSERT, END, ttk, LEFT, BOTTOM, X, RIGHT, Y, HORIZONTAL, BOTH
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x150+100+100')
root.resizable(0, 0)
# 创建一个滚动条控件,默认为垂直方向
sbar1=tk.Scrollbar(root)
# 将滚动条放置在右侧,并设置当窗口大小改变时滚动条会沿着垂直方向延展
sbar1.pack(side=RIGHT, fill=Y)
# 创建水平滚动条,默认为水平方向,当拖动窗口时会沿着X轴方向填充
sbar2 = tk.Scrollbar(root, orient=HORIZONTAL)
sbar2.pack(side=BOTTOM, fill=X)
# 创建列表框控件,并添加两个滚动条(分别在垂直和水平方向),使用 set() 进行设置
mylist = tk.Listbox(root, xscrollcommand=sbar2.set, yscrollcommand=sbar1.set)
for i in range(30):
mylist.insert(END, '第' + str(i+1)+'次:\n')
# 当窗口改变大小时会在X与Y方向填满窗口
mylist.pack(side=LEFT, fill=BOTH)
# 使用 command 关联控件的 yview、xview方法
sbar1.config(command=mylist.yview)
sbar2.config(command=mylist.xview)
# 显示窗口
root.mainloop()
通过滑动滚动条可以浏览列表框中的内容,垂直方向的滚动条沿着上下浏览,水平方向的滚动条则沿着左右方向浏览。
Tkinter Event事件处理
事件处理,是 GUI 程序中不可或缺的重要组成部分,相比来说,控件只是组成一台机器的零部件, 而事件处理则是驱动这台机器"正常"运转的关键所在,它能够将零部件之间"优雅"的贯穿起来,因此"事件处理"可谓是 GUI 程序的"灵魂",同时它也是实现人机交互的关键。
在一款 GUI 程序中,我们将用户对软件的操作统称为"事件",比如鼠标点击按钮、键盘输入文本以及窗口管理器触发的重绘事件等,这些事件有一个共同的特点,即都是由用户自身直接或者间接触发的。
事件绑定方法
Tkinter 提供的事件处理机制允许我们为"控件"绑定相应的事件和事件处理函数(即 callback函数),从而实现控件与用户的交互,其语法格式如下:
widget.bind("<event>",func)
上述语法中,widget 代表控件的实例对象,之后,采用 bind() 方法进行事件绑定,该函数有两个参数:
- <event>:一个字符串参数,表示事件的类型,并使用"尖括号"的形式进行包裹;
- func:表示事件的处理函数(callback,即回调函数),当触发事件时,Tk 会携带事件对象(Event)去调用 func 方法。
注意:bind() 方法可以完成事件与处理函数绑定,而使用 unbind() 方法可以将事件与处理函数解绑。
常用事件类型
事件类型(也称事件码)是 Tkinter 模块规定的,主要包括鼠标、键盘、光标等相关事件,Tkinter 为其规定了相应的语法格式:
<modifier-type-detail>
上述语法由三部分组成,说明如下:
- <>:事件类型必须包含在"尖括号"内;
- modifier:可选项,事件类型的修饰符,通常用于描述组合键、双击<Double-Button-1>、大写锁定键<Lock>以及<Alt-Shift>等;
- type:是必不可少的一项,表示事件的具体类型;
- detail:可选项,通常用于描述具体的哪个按键,比如 <Button-1> 表示鼠标左键;
对经常使用的 modifier 修饰符做简单的介绍,修饰符限制事件的激活条件,比如双击鼠标或者需要同时按下某个键才触发事件,常用的修饰符如下:
修饰符 | 说明 |
---|---|
Control | 事件发生时需按下 Control 键 |
Alt | 事件发生时需按下 Alt 键 |
Shift | 事件发生时需按下 Shift 键 |
Lock | 事件发生时需处于大写锁定状态 |
Double | 事件连续发生两次,比如双击鼠标 |
Triple | 事件连续发生三次 |
Quadruple | 事件连续发生四次 |
下述表格中介绍了 Tkinter 中经常使用的事件类型,如下所示:
事件码 | 说明 |
---|---|
<ButtonPress-1> | 单击鼠标左键,简写为<Button-1>,后面的数字可以是1/2/3,分别代表左键、中间滑轮、右键 |
<ButtonRelease-1> | 释放鼠标左键,后面数字可以是1/2/3,分别代表释放左键、滑轮、右键 |
<B1-Motion> | 按住鼠标左键移动,<B2-Motion>和<B3-Motion>分别表示按住鼠标滑轮移动、右键移动 |
<MouseWheel> | 转动鼠标滑轮 |
<Double-Button-1> | 双击鼠标左键 |
<Enter> | 鼠标光标进入控件实例 |
<Leave> | 鼠标光标离开控件实例 |
<Key> | 按下键盘上的任意键 |
<KeyPress-字母>/<KeyPress-数字> | 按下键盘上的某一个字母或者数字键 |
<KeyRelease> | 释放键盘上的按键 |
<Return> | 回车键,其他同类型键有<Shift>/<Tab>/<Control>/<Alt> |
<Space> | 空格键 |
<UP>/<Down>/<Left>/<Right> | 方向键 |
<F1>...<F12> | 常用的功能键 |
<Control-Alt> | 组合键,再比如<Control-Shift-KeyPress-T>,表示用户同时点击 Ctrl + Shift + T |
<FocusIn> | 当控件获取焦点时候触发,比如鼠标点击输入控件输入内容,可以调用 focus_set() 方法使控件获得焦点 |
<FocusOut> | 当控件失去焦点时激活,比如当鼠标离开输入框的时候 |
<Configure > | 控件的发生改变的时候触发事件,比如调整了控件的大小等 |
<Deactivate> | 当控件的状态从"激活"变为"未激活"时触发事件 |
<Destroy> | 当控件被销毁的时候触发执行事件的函数 |
<Expose> | 当窗口或组件的某部分不再被覆盖的时候触发事件 |
<Visibility> | 当应用程序至少有一部分在屏幕中是可见状态时触发事件 |
Event事件对象
当事件触发后,Tkinter 会自动将事件对象交给回调函数进行下步的处理,Event 对象包含了以下常用属性:
属性 | 说明 |
---|---|
widget | 发生事件的是哪一个控件 |
x,y | 相对于窗口的左上角而言,当前鼠标的坐标位置 |
x_root,y_root | 相对于屏幕的左上角而言,当前鼠标的坐标位置 |
char | 用来显示所按键相对应的字符 |
keysym | 按键名,比如 Control_L 表示左边的 Ctrl 按键 |
keycode | 按键码,一个按键的数字编号,比如 Delete 按键码是107 |
num | 1/2/3中的一个,表示点击了鼠标的哪个按键,按键分为左、中、右 |
width,height | 控件的修改后的尺寸,对应着 <Configure>事件 |
type | 事件类型 |
# 第三十五章节:Tkinter 事件绑定
import tkinter as tk
from tkinter import messagebox, INSERT, END, ttk, LEFT, BOTTOM, X, RIGHT, Y, HORIZONTAL, BOTH
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x150+100+100')
root.resizable(0, 0)
# 定义事件函数,必须用event参数
def show_key(event):
# 查看触发事件的按钮
s=event.keysym
# 将其显示在按钮控件上
lb.config(text=s)
# 添加一个按钮控件
lb = tk.Label(root, text='请按键', fg='blue', font=('微软雅黑', 15))
# 给按钮控件绑定事件,按下任意键,然后调用事件处理函数。注意,此处需要在英文状态下进行输入
lb.bind('<Key>', show_key)
# 设置按钮获取焦点
lb.focus_set()
lb.pack()
# 显示窗口
root.mainloop()
温馨提示:在上述示例中,只有当 Label 控件获取焦点后才能接收键盘事件,因此在给控件绑定事件和回调函数后,需要使用 focus_set() 方法来获取焦点。
鼠标事件示例:
# 第三十五章节:Tkinter 事件绑定:鼠标事件
import tkinter as tk
from tkinter import messagebox, INSERT, END, ttk, LEFT, BOTTOM, X, RIGHT, Y, HORIZONTAL, BOTH, RAISED, TOP
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x150+100+100')
root.resizable(0, 0)
def handleMotion(event):
lb1['text'] = '你移动了光标的所在位置'
lb2['text'] = '目前光标位置:x =' + str(event.x) + ';y=' + str(event.y)
print('光标当前位置', event.x, event.y)
# 创建一个窗体容器frame
frame = tk.Frame(root, relief=RAISED, borderwidth=2, width=300, height=200)
frame.bind('<Motion>', handleMotion)
lb1 = tk.Label(frame, text='没有任何事件触发', bg='purple', )
# 使用place进行位置布局,下一节会介绍
lb1.place(x=20, y=20)
lb2 = tk.Label(frame, text='')
lb2.place(x=16, y=60)
frame.pack(side=TOP)
# 显示窗口
root.mainloop()
Tkinter布局管理器
当我们在开发一个 GUI 程序的时候,布局管理发挥着非常重要的作用,它指的是通过管理控件在窗口中的位置(排版),从而实现对窗口和控件布局的目的。
Tkinter 提供了一系列布局管理的方法和容器控件,通过对这些内容的学习,您将掌握如何使用不同的方法完成界面布局。
Tkinter 提供了三种常用的布局管理器,分别是 pack()、grid() 以及 place(),如下表所示:
方法 | 说明 |
---|---|
pack() | 按照控件的添加顺序其进行排列,遗憾的是此方法灵活性较差 |
grid() | 以行和列(网格)形式对控件进行排列,此种方法使用起来较为灵活 |
place() | 可以指定组件大小以及摆放位置,三个方法中最为灵活的布局方法 |
pack()
pack() 是一种较为简单的布局方法,在不使用任何参数的情况下,它会将控件以添加时的先后顺序,自上而下,一行一行的进行排列,并且默认居中显示。pack() 方法的常用参数如下所示:
属性 | 说明 |
---|---|
anchor | 组件在窗口中的对齐方式,有 9 个方位参数值,比如"n"/"w"/"s"/"e"/"ne",以及 "center" 等(这里的 e w s n分别代表,东西南北) |
expand | 是否可扩展窗口,参数值为 True(扩展)或者 False(不扩展),默认为 False,若设置为 True,则控件的位置始终位于窗口的中央位置 |
fill | 参数值为 X/Y/BOTH/NONE,表示允许控件在水平/垂直/同时在两个方向上进行拉伸,比如当 fill = X 时,控件会占满水平方向上的所有剩余的空间。 |
ipadx,ipady | 需要与 fill 参数值共同使用,表示组件与内容和组件边框的距离(内边距),比如文本内容和组件边框的距离,单位为像素(p),或者厘米(c)、英寸(i) |
padx,pady | 用于控制组件之间的上下、左右的距离(外边距),单位为像素(p),或者厘米(c)、英寸(i) |
side | 组件放置在窗口的哪个位置上,参数值 'top','bottom','left','right'。注意,单词小写时需要使用字符串格式,若为大写单词则不必使用字符串格式 |
pack 方法示例:
# 第三十六章节:Tkinter 布局:pack
import tkinter as tk
from tkinter import messagebox, INSERT, END, ttk, LEFT, BOTTOM, X, RIGHT, Y, HORIZONTAL, BOTH, RAISED, TOP
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x150+100+100')
root.resizable(0, 0)
def handleMotion(event):
lb1['text'] = '你移动了光标的所在位置'
lb2['text'] = '目前光标位置:x =' + str(event.x) + ';y=' + str(event.y)
print('光标当前位置', event.x, event.y)
# 创建一个窗体容器frame
frame = tk.Frame(root, relief=RAISED, borderwidth=2, width=300, height=200)
frame.bind('<Motion>', handleMotion)
lb1 = tk.Label(frame, text='没有任何事件触发', bg='purple', )
# 使用place进行位置布局,下一节会介绍
lb1.place(x=20, y=20)
lb2 = tk.Label(frame, text='')
lb2.place(x=16, y=60)
frame.pack(side=TOP)
# 显示窗口
root.mainloop()
grid()
grid() 函数是一种基于网格式的布局管理方法,相当于把窗口看成了一张由行和列组成的表格。当使用该 grid 函数进行布局的时,表格内的每个单元格都可以放置一个控件。,从而实现对界面的布局管理。
注意:这里的所说的"表格"是虚拟出来,目的是便于大家理解,其实窗体并不会因为使用了 gird() 函数,而增加一个表格。
grid() 函数的常用参数如下所示:
属性 | 说明 |
---|---|
column | 控件位于表格中的第几列,窗体最左边的为起始列,默认为第 0 列 |
columnsapn | 控件实例所跨的列数,默认为 1 列,通过该参数可以合并一行中多个领近单元格。 |
ipadx,ipady | 用于控制内边距,在单元格内部,左右、上下方向上填充指定大小的空间。 |
padx,pady | 用于控制外边距,在单元格外部,左右、上下方向上填充指定大小的空间。 |
row | 控件位于表格中的第几行,窗体最上面为起始行,默认为第 0 行 |
rowspan | 控件实例所跨的行数,默认为 1 行,通过该参数可以合并一列中多个领近单元格。 |
sticky | 该属性用来设置控件位于单元格那个方位上,参数值和 anchor 相同,若不设置该参数则控件在单元格内居中 |
grid() 方法相比 pack() 方法来说要更加灵活,以网格的方式对组件进行布局管理,让整个布局显得非常简洁、优雅。如果说非要从三个布局管理器中选择一个使用的话,那么我推荐大家使用 grid() 方法。
温馨提示,在一个容器中不能同时使用 pack() 和 grid() 方法,这两个方法只能二选一,否则程序会运行错误。
grid 方法简单示例:
# 第三十六章节:Tkinter 布局:grid
import tkinter as tk
from tkinter import messagebox, INSERT, END, ttk, LEFT, BOTTOM, X, RIGHT, Y, HORIZONTAL, BOTH, RAISED, TOP
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x350+100+100')
root.resizable(0, 0)
# 在窗口内创建按钮,以表格的形式依次排列
for i in range(10):
for j in range(10):
tk.Button(root, text=" (" + str(i) + "," + str(j) + ")", bg='#D1EEEE').grid(row=i, column=j)
# 显示窗口
root.mainloop()
当使用 grid 函数布局的时,其实就是为各个控件指定行号、列号的过程,我们不需要为每个单元格指定大小,因为 grid 会为每个单元格自动设置一个适合的尺寸。
place()
与前两种布局方法相比,采用 place() 方法进行布局管理要更加精细化,通过 place() 布局管理器可以直接指定控件在窗体内的绝对位置,或者相对于其他控件定位的相对位置。
下面对 place 布局管理器的常用属性做相关介绍:
属性 | 说明 |
---|---|
anchor | 定义控件在窗体内的方位,参数值N/NE/E/SE/S/SW/W/NW 或 CENTER,默认值是 NW |
bordermode | 定义控件的坐标是否要考虑边界的宽度,参数值为 OUTSIDE(排除边界) 或 INSIDE(包含边界),默认值 INSIDE。 |
x、y | 定义控件在根窗体中水平和垂直方向上的起始绝对位置 |
relx、rely | 1. 定义控件相对于根窗口(或其他控件)在水平和垂直方向上的相对位置(即位移比例),取值范围再 0.0~1.0 之间 2. 可设置 in_ 参数项,相对于某个其他控件的位置 |
height、width | 控件自身的高度和宽度(单位为像素) |
relheight、relwidth | 控件高度和宽度相对于根窗体高度和宽度的比例,取值也在 0.0~1.0 之间 |
通过上述描述我们知道,relx
和rely
参数指定的是控件相对于父组件的位置,而relwidth
和relheight
参数则是指定控件相对于父组件的尺寸大小。
注意:这里父组件指的是当前可操作控件的上层组件,比如在没有使用容器控件(frame)的窗体中,控件的父组件就是主窗口本身,在《Tkinter布局管理容器控件》一节会做针对性介绍。
place 方法示例:
# 第三十六章节:Tkinter 布局:place
import tkinter as tk
from tkinter import messagebox, INSERT, END, ttk, LEFT, BOTTOM, X, RIGHT, Y, HORIZONTAL, BOTH, RAISED, TOP, SUNKEN, NE
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x350')
root.resizable(0, 0)
# 创建一个frame窗体对象,用来包裹标签
frame = tk.Frame(root, relief=SUNKEN, borderwidth=2, width=450, height=250)
# 在水平、垂直方向上填充窗体
frame.pack(side=TOP, fill=BOTH, expand=1)
# 创建 "位置1"
Label1 = tk.Label(frame, text="位置1", bg='blue', fg='white')
# 使用 place,设置第一个标签位于距离窗体左上角的位置(40,40)和其大小(width,height)
# 注意这里(x,y)位置坐标指的是标签左上角的位置(以NW左上角进行绝对定位,默认为NW)
Label1.place(x=40, y=40, width=60, height=30)
# 设置标签2
Label2 = tk.Label(frame, text="位置2", bg='purple', fg='white')
# 以右上角进行绝对值定位,anchor=NE,第二个标签的位置在距离窗体左上角的(180,80)
Label2.place(x=180, y=80, anchor=NE, width=60, height=30)
# 设置标签3
Label3 = tk.Label(frame, text="位置3", bg='green', fg='white')
# 设置水平起始位置相对于窗体水平距离的0.6倍,垂直的绝对距离为80,大小为60,30
Label3.place(relx=0.6, y=80, width=60, height=30)
# 设置标签4
Label4 = tk.Label(frame, text="位置4", bg='gray', fg='white')
# 设置水平起始位置相对于窗体水平距离的0.01倍,垂直的绝对距离为80,并设置高度为窗体高度比例的0.5倍,宽度为80
Label4.place(relx=0.01, y=80, relheight=0.4, width=80)
# 显示窗口
root.mainloop()
Tkinter布局管理控件
除了上一节《Tkinter布局管理方法》中提到的三个常用方法外,Tkinter 还提供了几个常用的布局管理控件,比如 Frame 、LabelFrame 等,这些控件的主要作用是为其他控件提供载体,并将主窗口界面划分成多个区域,从而方便开发者对不同区域进行设计与管理。
在前文讲解其他的 Tkinter 控件时,我们列举的大多数示例都是将控件直接放置在主窗口(即根窗口)内,这样做的目的是为了便于大家理解。但在实际的开发过程中,控件一般放置在容器中,比如 Frame 容器控件,如同 HTML 中的<div>
标签一样,把容器看做成一个框架,其他控件则是这个框架中的"元素"。
本节介绍了四种常用的容器控件以及它们的使用方法,分别是 Frame、LabelFrame、PanedWindow 以及 Toplevel。
Frame控件
Frame 本质上也是一个矩形窗体,同其他控件一样也需要位于主窗口内。我们可以在主窗口内放置多个 Frame 控件,并且每个 Frame 中还可以嵌套一个或者多个Frame,从而将主窗口界面划分成多个区域。
Frame 控件的常用属性如下表所示:
属性 | 说明 |
---|---|
bg | 设置 Frame 的背景颜色 |
bd | 指定 Frame 的边框宽度 |
colormap | 指定 Frame 组件及其子组件的颜色映射 |
container | 布尔值参数,若参数值为 True,则窗体将被用作容器使用,一些其他程序也可以被嵌入。 |
cursor | 指定鼠标在 Frame 上飘过的鼠标样式,默认由系统指定 |
height/width | 设置 Frame 的高度和宽度 |
highlightbackground | 指定当 Frame 没有获得焦点的时候高亮边框的颜色,通常由系统指定为标准颜色 |
highlightcolor | 指定当 Frame 获得焦点的时候高亮边框的颜色 |
highlightthickness | 指定高亮边框的宽度,默认值是 0 |
padx/pady | 距离主窗口在水平/垂直方向上的外边距 |
relief | 指定边框的样式,参数值 "sunken","raised","groove" 或 "ridge","flat",默认为 "falt' |
takefocus | 布尔值参数,默认为 False,指定该组件是否接受输入焦点(即用户通过 Tab 键将焦点转移上来) |
Frame控件 示例:
# 第三十六章节:Tkinter 布局控件:Frame
import tkinter as tk
from tkinter import messagebox, INSERT, END, ttk, LEFT, BOTTOM, X, RIGHT, Y, HORIZONTAL, BOTH, RAISED, TOP, SUNKEN, NE
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x350')
root.resizable(0, 0)
# 在主窗口上添加一个frame控件
frame1 = tk.Frame(root)
frame1.pack()
# 在frame_1上添加另外两个frame, 一个在靠左,一个靠右
# 左侧的frame
frame_left = tk.Frame(frame1)
tk.Label(frame_left, text='左侧标签1', bg='green', width=10, height=5).grid(row=0, column=0)
tk.Label(frame_left, text='左侧标签2', bg='blue', width=10, height=5).grid(row=1, column=1)
frame_left.pack(side=tk.LEFT)
frame_right = tk.Frame(frame1)
tk.Label(frame_right, text='右侧标签1', bg='gray', width=10, height=5).grid(row=0, column=1)
tk.Label(frame_right, text='右侧标签2', bg='pink', width=10, height=5).grid(row=1, column=0)
tk.Label(frame_right, text='右侧标签3', bg='purple', width=10, height=5).grid(row=1, column=1)
frame_right.pack(side=tk.RIGHT)
# 显示窗口
root.mainloop()
LabelFrame控件
LabelFrame 控件也是一种容器类型的控件,它属于是 Frame 控件的变体,因此它们的属性选项大体相同。
在默认情况下,LabelFrame 会在其包裹的子组件周围绘制一个边框和一个标题。当我们想要将一些相关的组件分为一组时,就可以使用 LabelFrame 组件,比如把一系列 Radiobutton(单选按钮)放在一起来供用户选择。
LabelFrame 控件示例:
# 第三十六章节:Tkinter 布局控件:LabelFrame
import tkinter as tk
from tkinter import messagebox, INSERT, END, ttk, LEFT, BOTTOM, X, RIGHT, Y, HORIZONTAL, BOTH, RAISED, TOP, SUNKEN, NE
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x450')
root.resizable(0, 0)
# 定义第一个容器,使用 labelanchor ='w' 来设置标题的方位
frame_left = tk.LabelFrame(root, text="教程", labelanchor="w", bg='#5CACEE')
# 使用 place 控制 LabelFrame 的位置
frame_left.place(relx=0.2, rely=0.2, relwidth=0.2, relheight=0.5)
label_1 = tk.Label(frame_left, text="C语言")
label_1.place(relx=0.2, rely=0.2)
label_2 = tk.Label(frame_left, text="Python")
label_2.place(relx=0.6, rely=0.2)
label_3 = tk.Label(frame_left, text="Java")
label_3.place(relx=0.2, rely=0.6)
label_4 = tk.Label(frame_left, text="C++")
label_4.place(relx=0.6, rely=0.6)
# 定义第二个容器,使用 labelanchor ='w' 来设置标题的方位
frame_right = tk.LabelFrame(root, text="辅导班", labelanchor="w", bg='#66CDAA')
# 使用 place 控制 LabelFrame 的位置
frame_right.place(relx=0.5, rely=0.2, relwidth=0.3, relheight=0.6)
label_1 = tk.Label(frame_right, text="C语言辅导班")
label_1.place(relx=0.2, rely=0.2)
label_2 = tk.Label(frame_right, text="数据结构")
label_2.place(relx=0.6, rely=0.2)
label_3 = tk.Label(frame_right, text="C++辅导班")
label_3.place(relx=0.2, rely=0.6)
label_4 = tk.Label(frame_right, text="Python答疑")
label_4.place(relx=0.6, rely=0.6)
# 显示窗口
root.mainloop()
PanedWindow控件
PanedWindow(窗格界面)也可以理解成一个特殊的 Frame 控件,它是 Tkinter 8.4 版本后新增的空间管理组件,其主要目的是为其他组件提供一个容器或者框架,从而实现以分块的形式对图形界面进行布局。
与 Frame 控件不同, PanedWindow 允许用户自主地调整界面划分以及每块区域的大小。因此,当您需要让用户自己调节每块区域的大小时,就可以采用 PanedWindow 作为组件载体来进行界面的布局。
不仅如此 PanedWindow 组件还提供了"手柄" 功能(设置参数 showhandle=True 来启用),通过拖动"手柄"图标也可以改变每块区域的大小。PanedWindow 组件语法格式如下所示:
PanedWindow(master=None, **options)
其中 master 表示父组件,即包裹该组件的上层组件。其常用属性如下表所示:
属性 | 说明 |
---|---|
handlepad | 1. 调节"手柄"的位置 2. 比如当 orient ='vertical' 设置垂直时,handlepad 表示"分割线"上的手柄与左端的距离,默认为 8 像素 |
handlesize | 设置"手柄"的尺寸(由于"手柄"必须是一个正方形,所以是设置正方形的边长)默认为 8 像素 |
opaqueresize | 1. 该选项定义了用户调整窗格尺寸的操作,如果该选项的值为 True(默认),窗格的尺寸随用户鼠标的拖拽而改变 2. 如果该选项的值为 False,那么窗格的尺寸,在用户释放鼠标时才会更新到新的位置上 |
orient | 指定窗格的分布方式,默认为水平方向分布("horizontal"),或者还可以设置为垂直纵向分布("vertical") |
relif | 指定边框的样式,默认为 "flat",还可以设置为 "sunken","raised","groove" 或 "ridge" |
sashpad | 设置每一条分割线到窗格间的间距 |
sashrelief | 设置分割线的样式,默认值是:"flat",还可以设置 "sunken","raised","groove" 或 "ridge" |
sashwidth | 设置分割线的宽度 |
showhandle | 设置是否显示调节窗格的手柄,默认为 False |
height/width | 设置 PanedWindow 的高度、宽度,若不设置,则其大小由其子组件的尺寸决定 |
PanedWindow 的常用方法如下表所示:
方法 | 说明 |
---|---|
add(child) | 添加一个新的子组件到窗格中语法格式 add(child,**option),参数值 after、before、sticky |
forget(child) | 删除一个子组件 |
panecget(child, option) | 获得子组件指定选项的值 |
paneconfig(child, **options) | 设置子组件的各种选项 |
panes() | 将父组件中包含的子组件以列表的形式返回 |
sash_coord(index) | 返回一个二元组表示指定分割线的起点坐标 |
sash_place(index, x, y) | 将指定的分割线移动到一个新的位置 |
PanedWindow 控件示例 :
# 第三十六章节:Tkinter 布局控件:PanedWindow
import tkinter as tk
from tkinter import messagebox, INSERT, END, ttk, LEFT, BOTTOM, X, RIGHT, Y, HORIZONTAL, BOTH, RAISED, TOP, SUNKEN, NE
root = tk.Tk()
root.title("Tkinter Text")
root.geometry('450x450')
root.resizable(0, 0)
# 创建一个水平方向的 panedwindow,并添加到主窗口中,默认为水平方向
p_window1 = tk.PanedWindow(root)
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='CSDN', 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='Java教程', 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)
# 显示窗口
root.mainloop()
Toplevel控件
Topleve 是一个顶级窗口控件(也被称为"子窗体"控件),同样类似于 Frame 控件, 不过该控件会脱离根窗口另行创建一个独立窗口,因此它的存在形式不同于上述其他容器。
Toplevel 控件同样隶属于主窗口的子组件,只是存在形式特殊而已。Toplevel 是主窗口之外的弹出框窗口(通过事件来触发执行),在这个窗口内也可以包含其他组件。但需要注意,顶级窗口并不是必须位于窗口的顶部位置,之所以称其为顶级窗口,是因为相对于主窗口而言,Topleve 位于主窗口的上一层。
Toplevel 控件拥有根窗口控件的所有方法和属性,同时它还拥有一些独有的方法,如下表所示:
方法 | 说明 |
---|---|
deiconify() | 在使用 iconify() 或 withdraw() 方法后,即窗口最小化和移除窗口后(只是看不见,并没销毁),使用该方法来显示该窗口 |
frame() | 返回一个系统特定的窗口识别码 |
group(window) | 将顶级窗口加入 window 窗口群组中,如果忽略该参数,将返回当前窗口群的主窗口 |
iconify() | 将窗口图标化(最小化),需要重新显示窗口,使用 deiconify() 方法 |
protocol(name, function) | 将回调函数 function 与相应的规则 name 绑定; 1) name 参数可以是 "WM_DELETE_WINDOW":窗口被关闭的时候; 2) name 参数可以是 "WM_SAVE_YOURSELF":窗口被保存的时候; 3) name 参数可以是 "WM_TAKE_FOCUS":窗口获得焦点的时候。 |
state() | 设置和获得当前窗口的状态,参数值 "normal"(正常状态),"withdrawn(移除窗口)","icon"(最小化)和 "zoomed"(放大) |
transient(master) | 指定为 master 的临时窗口 |
withdraw() | 将窗口从屏幕上移除,只是移动到了窗口之外,并没销毁,需要重新显示窗口,使用 deiconify() 方法 |
Toplevel 控件示例
# 第三十六章节:Tkinter 布局控件:Toplevel
import tkinter as tk
from tkinter import messagebox, INSERT, END, ttk, LEFT, BOTTOM, X, RIGHT, Y, HORIZONTAL, BOTH, RAISED, TOP, SUNKEN, NE
root = tk.Tk()
root.title("Tkinter 控件")
root.geometry('450x450')
root.resizable(0, 0)
def create_toplevel():
top = tk.Toplevel()
top.title("Tkinter Toplevel")
top.geometry('300x200+100+100')
# 多行文本显示Message控件
msg = tk.Label(top, text="www.google.com", bg='#9BCD9B', font=('宋体', 15))
msg.pack()
tk.Button(root, text="点击创建Toplevel组件", width=20, height=3, command=create_toplevel).pack()
# 显示窗口
root.mainloop()
Tkinter对话框控件
除了基本的控件之外,Tkinter 还提供了三种对话框控件:
- 文件选择对话框:filedailog
- 颜色选择对话框:colorchooser
- 消息对话框:messagebox
文件选择对话框
文件对话框在 GUI 程序中经常的使用到,比如上传文档需要从本地选择一个文件,包括文件的打开和保存功能都需要一个文件对话框来实现。Tkinter 提供文件对话框被封装在tkinter.filedailog
模块中,该模块提供了有关文件对话框的常用函数,经常使用的有以下几个:
方法 | 说明 |
---|---|
Open() | 打开个某个文件 |
SaveAs() | 打开一个保存文件的对话框 |
askopenfilename() | 打开某个文件,并以包函文件名的路径作为返回值 |
askopenfilenames() | 同时打开多个文件,并以元组形式返回多个文件名 |
askopenfile() | 打开文件,并返回文件流对象 |
askopenfiles() | 打开多个文件,并以列表形式返回多个文件流对象 |
asksaveasfilename() | 选择以什么文件名保存文件,并返回文件名 |
asksaveasfile() | 选择以什么类型保存文件,并返回文件流对象 |
askdirectory | 选择目录,并返回目录名 |
上述方法的常用参数值如下所示:
参数 | 说明 |
---|---|
defaultextension | 指定文件的后缀名,当保存文件时自动添加文件名,如果自动添加了文件的后缀名,则该选项值不会生效 |
filetypes | 指定筛选文件类型的下拉菜单选项,该选项值是由 2 元祖构成的列表,其中每个二元祖由两部分组成 (类型名,后缀),比如 filetypes = [("PNG","*.png"), ("JPG", "*.jpg"), ("GIF","*.gif"),("文本文件","*.txt")...] |
initialdir | 指定打开/保存文件的默认路径,默认路径是当前文件夹 |
parent | 如果不指定该选项,那么对话框默认显示在根窗口上,通过设置该参数可以使得对话框显示在子窗口上 |
title | 指定文件对话框的标题 |
文件选择对话框示例:
# 第三十六章节:Tkinter 文件选择对话框
import tkinter as tk
from tkinter import RAISED, filedialog
root = tk.Tk()
root.title("Tkinter 控件")
root.geometry('450x450')
root.resizable(0, 0)
# 定义一个处理文件的相关函数
def askfile():
# 从本地选择一个文件,并返回文件的目录
filename = filedialog.askopenfilename()
if filename != '':
lb.config(text=filename)
else:
lb.config(text='您没有选择任何文件')
btn = tk.Button(root, text='选择文件', relief=RAISED, command=askfile)
btn.grid(row=0, column=0)
lb = tk.Label(root, text='', bg='#87CEEB')
lb.grid(row=0, column=1, padx=5)
# 显示窗口
root.mainloop()
保存文件示例:
# 第三十六章节:Tkinter 文件选择对话框之文件保存
import tkinter as tk
from tkinter import RAISED, filedialog
from PIL import Image
root = tk.Tk()
root.title("Tkinter 控件")
root.geometry('450x450')
root.resizable(0, 0)
def open_img():
try:
global img
filepath = filedialog.askopenfilename() # 打开文件,返回该文件的完整路径
filename.set(filepath)
img = Image.open(filename.get())
except Exception as e:
print("您没有选择任何文件", e)
def save_png():
try:
filetypes = [("PNG", "*.png"), ("JPG", "*.jpg"), ("GIF", "*.gif"),("txt files", "*.txt"), ('All files', '*')]
# 返回一个 pathname 文件路径字符串,如果取消或者关闭则返回空字符,返回文件如何操作是后续代码的事情,
# 该函数知识返回选择文件的文件名字,不具备保存文件的能力
filenewpath= filedialog.asksaveasfilename(title='保存文件', filetypes=filetypes, defaultextension='.png', initialdir='C:/Users/Administrator/Desktop')
path_var.set(filenewpath)
# 保存文件
img.save(str(path_var.get()))
except Exception as e:
print(e)
filename = tk.StringVar()
path_var = tk.StringVar()
# 定义读取文件的组件
entry = tk.Entry(root, textvariable=filename)
entry.grid(row=1, column=0, padx=5, pady=5)
tk.Button(root, text='选择文件', command=open_img).grid(row=1, column=1, padx=5, pady=5)
# 定义保存文件的组件
entry1 = tk.Entry(root, textvariable=path_var)
entry1.grid(row=2, column=0, padx=5, pady=5)
tk.Button(root, text='保存文件', command=save_png).grid(row=2, column=1, padx=5, pady=5)
# 显示窗口
root.mainloop()
颜色选择对话框
颜色选择对话框(colorchooser),提供了一个非常友善的颜色面板,它允许用户选择自己所需要的颜色。 当用户在面板上选择一个颜色并按下"确定"按钮后,它会返回一个二元祖,其第 1 个元素是选择的 RGB 颜色值,第 2 个元素是对应的 16 进制颜色值。
颜色选择对话款主要应用在画笔、涂鸦等功能上,通过它可以绘制出五彩缤纷的颜色,该对话框的使用非常简单,主要有以下两个常用方法:
方法 | 说明 |
---|---|
askcolor() | 打开一个颜色对话框,并将用户选择的颜色值以元组的形式返回(没选择返回None),格式为((R, G, B), "#rrggbb") |
Chooser() | 打开一个颜色对话框,并用户选择颜色确定后,返回一个二元组,格式为((R, G, B), "#rrggbb") |
常用的颜色对话框的参数值如下表所示:
属性 | 说明 |
---|---|
default | 要显示的初始的颜色,默认颜色是浅灰色(light gray) |
title | 指定颜色选择器标题栏的文本,默认标题为"颜色" |
parent | 1. 如果不指定该选项,那么对话框默认显示在根窗口上 2. 如果想要将对话框显示在子窗口上,那么可以设置 parent = 子窗口对象 |
颜色对话框示例:
# 第三十六章节:Tkinter 颜色对话框
import tkinter as tk
from tkinter import RAISED, filedialog, colorchooser
root = tk.Tk()
root.title("Tkinter 控件")
root.geometry('450x450')
root.resizable(0, 0)
def callback():
# 打开颜色对话款
colorvalue = colorchooser.askcolor()
# 在颜色面板点击确定后,会在窗口显示二元组颜色值
lb.config(text='颜色值:'+ str(colorvalue))
lb=tk.Label(root, text='', font=('宋体', 10))
# 将label标签放置在主窗口
lb.pack()
tk.Button(root, text="点击选择颜色", command=callback, width=10, bg='#9AC0CD').pack()
# 显示窗口
root.mainloop()
消息对话框
关于消息对话款(messagebox),在前面介绍其他控件时已经使用过,在本节仅对它做简单介绍。
消息对话框主要起到信息提示、警告、说明、询问等作用,通常配合"事件函数"一起使用,比如执行某个操作出现了错误,然后弹出错误消息提示框。通过使用消息对话框可以提升用户的交互体验,也使得 GUI 程序更加人性化。消息对话框主要包含了以下常用方法:
方法 | 说明 |
---|---|
askokcancel(title=None, message=None) | 打开一个"确定/取消"的对话框 |
askquestion(title=None, message=None) | 打开一个"是/否"的对话框。 |
askretrycancel(title=None, message=None) | 打开一个"重试/取消"的对话框 |
askyesno(title=None, message=None) | 打开一个"是/否"的对话框 |
showerror(title=None, message=None) | 打开一个错误提示对话框 |
showinfo(title=None, message=None) | 打开一个信息提示对话框 |
showwarning(title=None, message=None) | 打开一个警告提示对话框 |
上述方法拥有相同的选项参数,如下表所示:
属性 | 说明 |
---|---|
default | 1. 设置默认的按钮(也就是按下回车响应的那个按钮) 2. 默认是第一个按钮(像"确定","是"或"重试") 3. 可以设置的值根据对话框函数的不同,可以选择 CANCEL,IGNORE,OK,NO,RETRY 或 YES |
icon | 1. 指定对话框显示的图标 2. 可以指定的值有:ERROR,INFO,QUESTION 或 WARNING 3. 注意:不能指定自己的图标 |
parent | 1. 如果不指定该选项,那么对话框默认显示在根窗口上 2. 如果想要将对话框显示在子窗口上,那么可以设置 parent= 子窗口对象 |
上述方法的返回值一般会是一个布尔值,或者是"YES","NO","OK"等,这些方法使用较为简单,此处不进行逐一列举,看个简单的示例即可:
# 第三十六章节:Tkinter 消息对话框
import tkinter as tk
from tkinter import RAISED, filedialog, colorchooser
root = tk.Tk()
root.title("Tkinter 控件")
root.geometry('450x450')
root.resizable(0, 0)
def callMessageDialog():
result = tk.messagebox.askokcancel("提示", " 你确定要关闭窗口吗? ")
# 返回布尔值参数
print(result)
tk.Button(root, text="点击消息对话框", command=callMessageDialog, width=10, bg='#9AC0CD').pack()
# 显示窗口
root.mainloop()
本文参考:Tkinter 教程