Tkinter 二万五千字!!

tkinter是python自带库其中之一,其核心功能是GUI开发,操作比较简单。所以如果想要GUI编程,tkinter是一个不错的选择,不需要什么额外的环境,只需电脑中安装python即可。但在学习之前,需要了解由tkinter开发出来的界面并不算很好看,有很浓厚的“复古感”。

其实对于前端或者GUI开发都有异曲同工之妙,因为本质上都可以看做是设计界面。一个界面是由组件和交互组成,其中组件又可以分为组件内容和组件样式。

  • 组件内容:就是在界面中要展示的内容,对于HTML可以是<button>,<text>等标签,对于tkinter可以是entry(),label()组件,通过这些来标记要显示在界面中的部分,比如可以使用button的标签或者组件在界面中就可以得到一个按键。
  • 组件样式:作为一个展示所用的界面,好看的界面就像美术展的艺术品,使用户会有舒适的体验。如果做过前端的肯定很清楚如果只使用HTML来搭建网页,其最终展示的效果肯定是挤成一团,所以我们需要通过改变样式来改善我们页面的观感。而基础的样式又可以分作属性配置和布局配置(因为对css动画等更高级的用法掌握并不好,所以可能是最基础的进行分类吧)
    • 属性配置:例如组件的背景颜色,字体颜色,字体大小,内边距,外边距等。这些配置可以更改组件的表现形式,就像一个人的身高体重性别,只与对象本身相关的属性。对于Tkinter,这些参数就内嵌在对象本身中,详情会在后面介绍。
    • 布局配置:界面开发当然也要涉及设计,可以浅显的理解成室内设计,相比于室内设计是设置家具在房间内的位置,而布局配置类似的是设置每个组件的摆放位置。相比于于HTML,一旦文件中添加了标签,那在界面中就默认按照流式方式显示出来,而对于Tkinter,需要添加几何管理的方法才会在界面中显示。
  • 交互:对于GUI全称为(Graphics User Interface)即图像用户界面,出现目的就是代替命令行界面来进行学习代价更低的图像方式来使用计算机,如果只展示界面优美的组件布局,大可去开办一个艺术展。所以GUI和画最大的区别,就是可以与人进行交互。例如:当我们点击按键,会有一个弹窗或者执行某些动作,这些关于Tkinter的交互设置,会在后面介绍。

笔记参考:TK学习文档1文档2

🎈由示例了解Tkinter

from tkinter import *
from tkinter import ttk

在代码中导入tkinter库,其中第一句采用全导入的方式导入tkinter库。

而由于此库中组件相对来说比较“丑陋”,为了美观一点,自从tkinter8.5之后就推出了ttk(其实也并不好看,但好在可以自定义组件样式,比如衍生库ttkbootstrap。对于学过前端的应该对bootstrap很熟悉),其中ttk中的组件和tkinter组件使用方式几乎一样。

root = Tk()
root.title("英寸转换")

首先通过Tk()创建一个实例,这是整个GUI的最底层也就是顶级窗口,别的组件创建或多或少都需要依赖这个。为了方便理解,可以把GUI想象的和高楼一样,对于平常我们都是以俯视图去观察,所以会感觉都在一个层面之上。但如果换成正视图, 就变成了高楼林立。而组件可以分布在各楼层,对于创建的root,是最底层就可以理解成是地基

第二局就很好理解,设置窗口的标题。

mainframe = ttk.Frame(root)
mainframe.grid()

创建一个Frame,对照上面的理解相当于盖了一层楼,在创建的过程中传递的参数是root,其实就相当于我要把组件(Frame本质上也是组件)盖在哪里,所以就可以知道这是建造在”地基“上的”第一层楼“。

在然后把该Frame组件放置在”地基“上,也就是我要把该层楼盖在哪里,对于grid()会有详细介绍使用方法,这里只需知道是用来把组件盖出来,采用表格方式。

feet = StringVar()
feet_entry = ttk.Entry(mainframe, width=7, textvariable=feet)
feet_entry.grid(column=2, row=1, sticky=(W, E))

创建一个输入框组件,这里引入一个双向绑定变量feet,这样就能获取用户在输入框的输入信息,以方便在程序中进行逻辑操作。

meters = StringVar()
ttk.Label(mainframe, textvariable=meters).grid(column=2, row=2, sticky=(W, E))

创建一个标签组件,同时也引入一个双向绑定变量meters,既然双向绑定,可以获取组件内容,同理也可以通过设置变量内容实现改变组件内容的操作。

def calculate(*args):
    try:
        value = float(feet.get())
        meters.set(int(0.3048 * value * 10000.0 + 0.5)/10000.0)
    except ValueError:
        pass

ttk.Button(mainframe, text="Calculate", command=calculate).grid(column=3, row=3, sticky=W)

创建一个按键组件,并通过command参数绑定按键按下后的回调函数,函数逻辑相对来说很简单,获取输入框的内容,并通过转换计算设置标签内容。其中可以看到,对于双向绑定变量,获取其值是采用get()方法,而设置其值是采用set()方法

ttk.Label(mainframe, text="英寸").grid(column=3, row=1, sticky=W)
ttk.Label(mainframe, text="转换成米制就是").grid(column=1, row=2, sticky=E)
ttk.Label(mainframe, text="米").grid(column=3, row=2, sticky=W)

创建几个标签组件用来设置提示信息。

可以看到对于标签、输入框、和按键的创建,传递的第一个父组件都是最开始创建的框架Frame,如果按照楼房理解的话,Frame还是扮演楼层的角色,而对于标签、输入框、和按键这些组件就可与理解成这一层的家具,比如冰箱 电视之类的。可以对比着理解Frame这个组件,其功能就是用来“盖楼”!

细心观察的话可以看到,对于Frame和输入框在创建的时候,会有一个组件变量用来接受实例化的对象,而对于标签和按键的创建并没有这一个操作。对于这个到底需不需要有这样一个变量,主要是看在编码中是否需要对该组件本身进行操作,比如Frame因为后几个组建的的创建都需要其作为父组件,而对于输入框需要设置其获取焦点,所以也要有一个变量。

feet_entry.focus()
root.bind("<Return>", calculate)
root.mainloop()

设置输入框焦点,也就是当GUI出现之后,输入框就会有焦点,用户可以直接点击键盘输入内容,而不是先用鼠标点击一下获取焦点。

对整个GUI界面采取事件绑定,对于<Return>表示用户按下Enter回车键执行calculate函数相当于按下按键。注意主要是关于root的设置都是对整个GUI界面的操作,谁让整个界面都是由它承上启下实现的。

最后调用mainloop()这是一个死循环,用来更新GUI界面,监听用户事件。一句话,最后如果不调用这个函数,那这个家要散。

全部代码

from tkinter import *
from tkinter import ttk


def calculate(*args):
    try:
        value = float(feet.get())
        meters.set(int(0.3048 * value * 10000.0 + 0.5) / 10000.0)
    except ValueError:
        pass


root = Tk()
root.title("英寸转换")

mainframe = ttk.Frame(root)
mainframe.grid()

feet = StringVar()
feet_entry = ttk.Entry(mainframe, width=7, textvariable=feet)
feet_entry.grid(column=2, row=1, sticky=(W, E))

meters = StringVar()
ttk.Label(mainframe, textvariable=meters).grid(column=2, row=2, sticky=(W, E))

ttk.Button(mainframe, text="Calculate", command=calculate).grid(column=3, row=3, sticky=W)

ttk.Label(mainframe, text="英寸").grid(column=3, row=1, sticky=W)
ttk.Label(mainframe, text="转换成米制就是").grid(column=1, row=2, sticky=E)
ttk.Label(mainframe, text="米").grid(column=3, row=2, sticky=W)


feet_entry.focus()
root.bind("<Return>", calculate)
root.mainloop()

效果:

在这里插入图片描述

🎨TK概念

对于GUI的概念其实可以对等于前端开发的知识,总所周知前端三剑客(HTML+CSS+JavaScript),同理Tkinter开发也有组件、几何管理、事件处理。对于前端来说,HTML通过标签的方式创建网页的文档结构,也就是网页的内容、CSS添加格式和样式来美化网页、JavaScript用于使网站具有交互性。

🎃组件

组件即是内容。

组件是在屏幕上看到的所有东西,比如按键、输入框、标签、框架,其实对于TK()实例也算一个特殊的组件。

标准属性

每个组件都有一组影响其外观和行为的选项——诸如字体、颜色、大小、文本标签等属性。可以在调用组件的构造函数时使用关键字参数指定选项,例如text='PANIC!'或height=20。创建组件之后,也可以使用组件的.config()方法更改任何选项

所有组件都有属性,组件的可用选项取决于组件的功能,不同的组件之间有很多一致性,所以做类似效果的选项往往被命名为相同的。例如,按钮和标签都有文本选项来调整组件显示的文本,而滚动条没有文本选项,因为不需要。类似地,按钮有一个命令选项,告诉它在按下时该做什么,而仅保存静态文本的标签则没有。

可以通过configure()方法来获取组件的选项以及当前选项信息,由于返回值是一个字典,就可以直接使用keys()方法来获取该按键选项具体操作如下

print(ttk.Label().configure().keys())
'''
>>输出
dict_keys(['background', 'foreground', 'font', 'borderwidth', 'relief', 'anchor', 'justify', 'wraplength', 'takefocus', 'text', 'textvariable', 'underline', 'width', 'image', 'compound', 'padding', 'state', 'cursor', 'style', 'class'])
'''
长度单位

组件的各种长度、宽度和其他尺寸可以用许多不同的单位来描述。如果只使用整数不带各种符号,那单位就是像素,例如上面的height=20就是表示设置长度为20像素。可以通过将参数设置为包含数字的字符串来指定单位。

  • 20c:20厘米
  • 20i:20英寸
  • 20m:20毫米
  • 20p:20打印机点数(约1/72″)
颜色color

Tkinter中有两种方法来指定颜色

  1. 可以使用字符串以十六进制数字指定红、绿、蓝的比例
    1. #rgb:每个颜色4位
    2. #rrggbb:每个颜色8位
    3. #rrrgggbbb:每个颜色12位
  2. 可以使用任何本地定义的标准颜色名称。'white','black','red','green','blue','cyan','yellow'
字体font

对于指定字体的操作有两种

  1. 使用一个元组,其第一个参数表示字体族如我们在word文件中常使用的"宋体",“楷体”,“微软雅黑”,第二个参数表示字体大小其中如果数值为正,则以点数为单位,如果为负,则以像素为单位,第三个参数可选是包含一个或多个样式修饰符的字符串可使用的有bold加粗、italic斜体、underline下划线、overstrike删除线

    ttk.Label(parent,text="字体font测试",font=("宋体",20,"bold"))
    
  2. 使用字体对象的形式,通过导入font模块并使用其Font类构造函数

    from tkinter import font
    
    Myfont=font.Font(family="华文楷文",size=20,weight=font.BOLD,slant=font.ITALIC,underline=1,overstrike=1)
    ttk.Label(parent,text="字体font测试",font=Myfont)
    
    # 获取平台上所有可用字体的列表
    print(font.families())
    
    选项选项内容
    family字体族
    size尺寸-如果数值为正,则以点数为单位,如果为负,则以像素为单位
    weight'bold'表示粗体, 'normal' 表示正常
    slant'italic'表示斜体,'roman'表示不倾斜。
    underline1表示下划线,0表示无操作
    overstrike1表示删除线,0表示无操作

    若界面中需要多个组件需要相同的字体类型,相比于第一种一个一个去配,使用字体对象就能大大提高代码的简洁和可维护性。

浮雕样式relief

组件的浮雕样式是指围绕组件外部的某种模拟三维效果。

ttk.Label(self, borderwidth=1, relief="raised", text="raised").grid(column=0, row=0, padx=10, pady=10)
ttk.Label(self, borderwidth=2, relief="ridge", text="ridge").grid(column=0, row=1, padx=10, pady=10)
ttk.Label(self, borderwidth=3, relief="sunken", text="sunken").grid(column=0, row=2, padx=10, pady=10)
ttk.Label(self, borderwidth=4, relief="flat", text="flat").grid(column=0, row=3, padx=10, pady=10)
ttk.Label(self, borderwidth=5, relief="groove", text="groove").grid(column=0, row=4, padx=10, pady=10)
ttk.Label(self, borderwidth=6, relief="ridge", text="solid").grid(column=0, row=5, padx=10, pady=10)

效果图:

在这里插入图片描述

这些边框的宽度取决于组件的borderwidth选项。但只对原生组件有效果,对于ttk的组件没有什么作用。

鼠标游标cursor

通过不同参数改变鼠标经过组件的样式

使用方法:

Button(root,text='cursors_Test',cursor='circle').pack()

举例:

在这里插入图片描述

参考:

python中Tkinter的鼠标样式cursor(带图示)_tkinter cursor-CSDN博客

python中tkinter较完整的鼠标样式cursor值_tkinter cursor-CSDN博客

图像Images

在Tkinter界面中显示图形图像有三种常用方法。而对于图像只能在例如Labal组件中有image属性来展示图像,并没有一个Image组件。

  1. 要以.xbm格式显示位图(双色)图像

    #f:文件名 background:背景 foreground:前景 通常对于二色图 前景会显示黑色 背景显示白色 可以通过如此更改显示颜色
    tkinter.BitmapImage(file=f[, background=b][, foreground=c])
    #使用
    logo = tkinter.BitmapImage('logo.xbm', foreground='red')
    Label(image=logo).grid()
    
  2. .gif,.pgm,.ppm格式显示全色图

    同第一种形式差不多

    #f:文件名
    tkinter.PhotoImage(file=f)
    #使用
    logo = tkinter.PhotoImage('logo.xbm')
    Label(image=logo).grid()
    
  3. 使用Python图像库PIL其中的ImageTk类能支持大多数类型的图片,对于ImageTk类专门为在Tkinter界面中显示图像而设计的。

    from PIL import Image, ImageTk
    img_open = Image.open('test.jpg')
    img = ImageTk.PhotoImage(img_open)
    Label(root, image = img).pack()
    

    相比于前两种,格式的古老,第三种使用图片的方式是最常用的。

系统组件

这里介绍的组件除了顶级窗口外,都是源自ttk的组件,会与tkinter原生组件有一些差别。ttk组件提供更加现代化的外观,并且支持样式的自定义,可以看到相比于tkinter其上限比较高,下面是一些官方介绍。

Tk 8.5开始,引入了ttk模块。这个模块取代了大部分(但不是全部)原始的Tkinter模块。使用该模块可以获得以下优势:

  • 特定于平台的外观。在Tk 8.5之前的版本中,对Tk界面最常见的抱怨之一是它们不符合各种平台的风格。ttk模块允许以通用的方式编写界面,界面在Windows系统下看起来像Windows界面,在MacOS系统下看起来像MacOS界面等,而无需对程序进行任何更改。

  • 可以使用ttk内置主题、或自定义主题、也可以使用ttkthemes和ttkboostrap第三方主题来美化界面。(这个会单独来介绍,这里只是提出使用ttk的优势)。

  • 对于组件的属性配置更加简化,相比原生的Tkinter组件,有很多选项可以根据不同的条件指定组件的外观或行为。而ttk组件相对来说就精简很多,这也是和原生组件的最大差别。例如,原生按钮组件有几个不同的选项来控制前景(文本)颜色。

    • 当光标位于按钮上方时,使用activeforeground颜色。
    • 当组件被禁用时,使用disabledforeground颜色。
    • 当其他条件不适用时,使用foreground颜色。

    ttk模块将这些特殊情况分解成一个简单的两部分系统:

    • 每个组件都有许多不同的状态,每个状态都可以独立于其他状态打开或关闭。状态的例子有:disabled、active和focus
    • 您可以设置一个style映射,根据状态或组件状态的组合来指定特定的状态设置为确切的值。

对于ttk组件的相关属性,相比原生组件会少了许多,但不代表做不了相关的效果,因为只是构造器不支持,但可以用style设置

顶级窗口

这是界面最先开始的地方!!牛到没有父组件,因为这个就是老祖宗

root = TK()

顶级窗口选项:

选项选项介绍
width所需的窗口宽度。
height窗口高度。
bgorbackground窗口的背景颜色。
highlightbackground当窗口没有焦点时,焦点突出显示的颜色。
highlightcolor当窗口有焦点时,焦点突出显示的颜色。
highlightthickness聚焦高光的厚度。默认值为1。设置highlightthickness=0以抑制焦点高亮显示。
menu为该窗口提供一个顶级菜单栏。
padx使用此选项可在窗口的左右两侧提供额外的空间。该值是一个像素数。
pady使用此选项可以在窗口的顶部和底部提供额外的空间。该值是一个像素数。
cursor使用此选项指定鼠标光标在组件上方时的外观,在标准属性中有介绍。
bdorborderwidth边框宽度(像素),默认为0。
relief指定边框的浮雕样式,在标准属性中有介绍。若borderwidth为0,则没有效果。
takefocus使用此选项指定在焦点遍历期间是否访问组件,关于其作用在路由键盘输入介绍。

顶级窗口方法:

方法方法介绍
.deiconify()如果此窗口已最小化,展开它
.geometry(newGeometry=None)设置窗口几何形状。"wxh±x±y"
.iconify()最小化窗口。
.title(text=None))设置窗口标题。
.iconbitmap(filename)设置窗口图标(图标是.ico文件类型)
.attributes(attr,param)用来设置窗口的一些属性,比如透明度(-alpha)、是否置顶(-topmost)、是否全屏(-fullscreen)全屏显示等
.resizable(width=None, height=None)如果为true,则允许调整大小。
框架ttk.Frame

框架基本上只是其他组件的容器。

  • 界面的根窗口也就是顶级窗口基本上是一个框架
  • 每个框架都有自己的Grid布局,因此每个框架内的组件网格化是独立工作的。
  • 框架组件是使界面模块化的重要工具。可以通过将一组相关组件放入框架中,将它们分组为复合组件。也可以声明一个继承Frame的新类,并向其添加您自己的接口。这是向外界隐藏一组相关组件内交互细节的好方法。

在名为parent的顶级窗口或框架中创建一个新的框架组件:

w = ttk.Frame(parent, option=value, ...)

框架组件选项:

选项选项介绍
height设置组件高度,单位在标准属性中有介绍。若使框架具有设置的高度,使用组件上的.grid_propagate(0)方法。
width设置组件宽度,单位在标准属性中有介绍。若使框架具有设置的宽度,使用组件上的.grid_propagate(0)方法。
cursor使用此选项指定鼠标光标在组件上方时的外观,在标准属性中有介绍。
relief指定边框的浮雕样式,在标准属性中有介绍。若borderwidth为0,则没有效果。
borderwidth使用此选项可指定边框元素的宽度,默认值为零,单位在标准属性中有介绍。
padding在框架内部和包含的组件外部创建一个空白区域,单位在标准属性中有介绍。例如,padding='0.5c'将填充框架内以及框架内组件的外部半厘米宽的区域。
style使用此选项指定自定义组件样式名称,关于其在自定义和创建主题和样式介绍。
takefocus使用此选项指定在焦点遍历期间是否访问组件,关于其作用在路由键盘输入介绍。

关于grid_propagate(0)方法:通常,所有组件会适应界面几何管理,这意味着它们会调整以适应内容。但是,有时希望强制一个组件具有一定的大小,而不管其内容的大小。为此,调用w.grid_propagate(0),其中w是要强制其大小的组件。对于长宽只需调用一次就都确定了。

标签ttk.Labal

这个组件的目的是显示文本、图像,或者两者都显示。通常内容是静态的,但是程序可以更改文本或图像就如示例展示那样

在名为parent的顶级窗口或框架中创建一个新的标签组件:

w = ttk.Label(parent, option=value, ...)

标签组件选项:

选项选项介绍
text要在组件中显示的文本字符串。
textvariableStringVar实例,如果设置这个会忽略掉text设置的值,用来动态改变标签值。
image此选项指定一个或多个图像要在文本之外或代替文本显示,关于图像在标准属性中有介绍。
compound如果同时提供文本和图像选项,则复合选项指定如何显示它们。
width若要指定固定宽度,请将此选项设置为字符数。若要指定最小宽度,请将此选项设置为负字符数。如果不指定此选项,则标签区域的大小将刚好能够容纳当前文本和(或)图像。也可以使用style指定此选项。
wraplength单行最大尺寸,如果超过文本会自动换行。也可以使用style指定此选项。
anchor如果文本和(或)图像小于指定的宽度,可以使用此选项来指定它们的位置:tk.W, tk.CENTER,或tk.E分别代表左、中、右对齐,也可以使用style指定此选项。
justify如果提供的文本包含换行符('\n'),此选项指定每行如何水平对齐(tk.LEFTtk.CENTERtk.RIGHT ),也可以使用style指定此选项。
font使用此选项可指定显示文本的字体样式,在标准属性中有介绍。也可以使用style指定此选项。
background使用此选项设置背景颜色,也可以使用style指定此选项。
foreground使用此选项可指定显示文本的颜色。也可以使用style指定此选项。
relief指定边框的浮雕样式,在标准属性中有介绍。若borderwidth为0,则没有效果。也可以使用style指定此选项。
borderwidth使用此选项可指定边框元素的宽度,默认值为零,单位在标准属性中有介绍。
cursor使用此选项指定鼠标光标在组件上方时的外观,在标准属性中有介绍。
padding在文本和(或)图像的四周添加更多空间,将此选项设置为所需的尺寸,单位在标准属性中有介绍。也可以使用style指定此选项。
underline通过将此选项设置为文本字符串中的某个字母的位置,可以请求将该字母下划线。例如,选项text='Quit'和underline=0将给Q加下划线。
style使用此选项指定自定义组件样式名称,关于其在自定义和创建主题和样式介绍。
takefocus使用此选项指定在焦点遍历期间是否访问组件,关于其作用在路由键盘输入介绍。
关于compound属性:
  • 'top':在文本上方显示图像
  • 'bottom':在文本下方显示图像
  • 'left':在文本左方显示图像
  • 'right':在文本右方显示图像
  • 'image':只显示图像,不显示文本
  • 'text':只显示文本,不显示图像
  • 'none':如果有图像则显示图像,否则显示文本,默认值
关于image属性:

图像的值在标准属性中已经介绍过了,相比于任何情况下都是同一种图片,也可以根据组件的状态指定将出现在组件上的多个图像。为此,提供一个元组(i0, s1, i1, s2, i2,…)作为该选项的值,其中:

  • i0是要在组件上显示的默认图像
  • 对于第一个值之后的每一对值,sn指定一个状态或状态组合,in指定当组件的状态与sn匹配时要显示的图像

每个状态说明符sn可以是单个状态名,前面可以加'!',或者一系列这样的名字。'!'指定组件不能处于该状态。例如:

w = ttk.Label(parent,image=(im1,'selected', im2,('!disabled', 'alternate'), im3), ...)
按钮ttk.Button

就是一个按钮,内部可以认为内嵌了一个Labal组件

在名为parent的顶级窗口或框架中创建一个新的按钮组件:

w = ttk.Button(parent, option=value, ...)

按钮组件选项:

选项选项介绍
command按下按钮时调用的函数。
text要显示在按钮上的文本。
textvariableStringVar实例,如果设置这个会忽略掉text设置的值,用来动态改变标签值。
image按钮上显示的图像,关于图像在标准属性中有介绍。
compound详情查看关于compound属性
width如果内容是文本,则此选项指定按钮上文本区域的绝对宽度,以字符数表示;实际宽度是该数字乘以当前字体中字符的平均宽度。对于图像标签,此选项将被忽略。也可以使用style指定此选项。
underline通过将此选项设置为文本字符串中的某个字母的位置,可以请求将该字母下划线,同Labal组件。
cursor使用此选项指定鼠标光标在组件上方时的外观,在标准属性中有介绍。
style使用此选项指定自定义组件样式名称,关于其在自定义和创建主题和样式介绍。
takefocus使用此选项指定在焦点遍历期间是否访问组件,关于其作用在路由键盘输入介绍。
输入框ttk.Entry

允许用户输入或编辑单行文本

在名为parent的顶级窗口或框架中创建一个新的输入框组件:

w = ttk.Entry(parent, option=value, ...)

输入框组件选项:

选项选项介绍
textvariableStringVar实例,如果设置这个会忽略掉text设置的值,用来动态改变标签值。
show要保护密码等字段在屏幕上不可见,请将此选项设置为字符串,其第一个字符将替换字段中的每个实际字符。例如,如果字段包含“sesame”,但您指定了show=“*”,则该字段将显示为“******”。
font使用此选项可指定显示文本的字体样式,在标准属性中有介绍。不可以使用style指定此选项!!
justify选项指定当文本没有完全填满输入区域时,文本将如何在该区域内定位tk.LEFTtk.CENTERtk.RIGHT
validate可以使用此选项设置组件,以便在特定时间由验证函数检查其内容。
validatecommand验证组件文本的回调,其返回值的bool值若输入检测合规则是true否则为false
invalidcommand将此选项设置为一个回调函数,该函数将在验证失败时调用(当validatcommand返回0时)。
xscrollcommand如果用户输入的文本经常超过组件的屏幕大小,那么可以将输入组件链接到滚动条。将此选项设置为滚动条的.Set方法。
exportselection默认可以在Entry组件中选择文本,自动导出到剪贴板。要避免导出,请使用exportselection=0
width组件的大小(以字符为单位)。默认值是20。
cursor使用此选项指定鼠标光标在组件上方时的外观,在标准属性中有介绍。
style使用此选项指定自定义组件样式名称,关于其在自定义和创建主题和样式介绍。
takefocus使用此选项指定在焦点遍历期间是否访问组件,关于其作用在路由键盘输入介绍。
关于输入框添加滚动框xscrollcommand

使Entry组件可滚动需要编写一些额外的代码,以使Scrollbar组件的回调适应Entry组件上可用的方法

  1. 首先,Entry和Scrollbar组件的创建和链接

    # 创建Entry组件
    self.entry = ttk.Entry(self, width=10)
    self.entry.grid(row=0, sticky=E + W)
    # 创建Scrollbar组件
    self.entryScroll = ttk.Scrollbar(self, orient=HORIZONTAL,
                                     command=self.__scrollHandler)
    self.entryScroll.grid(row=1, sticky=E + W)
    # 设置Entry组件的xscrollcommand属性 注意set属性
    self.entry['xscrollcommand'] = self.entryScroll.set
    
  2. 编写上面所说的处理函数__scrollHandler

    def __scrollHandler(self, *L):
        op, howMany = L[0], L[1]
    
        if op == 'scroll':
            units = L[2]
            self.entry.xview_scroll(howMany, units)
        elif op == 'moveto':
            self.entry.xview_moveto(howMany)
    

效果图:

在这里插入图片描述

关于向Entry组件添加输入验证:

在某些界面中,需要检查Entry组件的内容,以确保它们根据界面必须执行的某些规则是有效的。例如对于电话号只能输入11位纯数字,可以通过编写一个回调函数来定义什么是有效的,该函数检查内容并发出是否有效的信号。

在组件上设置验证的过程:

  1. 编写一个回调函数,检查输入框中的文本,如果文本有效则返回True,否则返回False。如果回调返回False,用户编辑文本的尝试将被拒绝,文本将保持不变。关于文本的检测逻辑可以使用正则表达式

    def isOkay(self, why, where, what):
            ...
    
  2. 注册回调函数。使用register方法,这个方法返回一个字符串,Tkinter可以用它来调用第一步设置的回调函数。

    okayCommand = self.register(isOkay)
    
  3. 在调用Entry构造函数时,使用Entry构造函数中的validatcommand选项指定回调,并使用validate选项指定何时调用回调以验证回调中的文本。其中'%d', '%i', '%S'为参数占位符,对应着回调函数的why, where, what参数

    w = ttk.Entry(parent, validate='all',validatecommand=(okayCommand, '%d', '%i', '%S'), ...
    

validate:表示对输入框执行什么操作时,才调用函数来检测是否符合规则

  • focus:在Entry组件获得焦点或失去焦点时进行验证。
  • focusin:在组件获得焦点时进行验证。
  • focusout:在组件失去焦点时进行验证。
  • key:每当任何击键改变组件的内容时,都要进行验证。
  • all:在上述所有情况下进行验证
  • none:关闭验证。这是默认选项值。请注意,这是字符串'none',而不是Python的特殊值none

validatecommand:对于该选项的值取决于您希望回调接收的参数。

  • 如果回调函数需要知道的唯一一件事就是Entry中当前出现的文本。可以使用与组件关联的textvariable变量的.get()方法来获取该文本。在上面例程中只需设置validatecommand=okayCommand而不是一个元组。
  • Tkinter还可以为回调提供许多项信息。如果希望使用其中的一些项,在调用Entry构造函数时,设置选项validatcommand =(f, s1, s2,…),其中f是回调函数的名称,每个额外的si是占位符。对于提供的每个占位符,回调将接收一个包含对应值的位置参数。
    • '%d':操作代码:0表示尝试删除,1表示尝试插入,或者-1表示因焦点获得失去或对textvariable变量的更改而调用回调。
    • '%i':当用户尝试插入或删除文本时,此参数将是插入或删除开始的索引。如果回调是焦点获得失去或对textvariable变量的更改,则参数将为-1。
    • '%P':如果允许更改,输入框将具有的值。
    • '%s':更改前组件中的文本。
    • '%S':如果函数调用是由于插入或删除,则此参数将是插入或删除的文本。
    • '%v':组件的validate选项的当前值。
    • '%V':这个回调的原因:'focusin', 'focusout', 'key''forced'如果textvariable被更改。
    • '%W':组件的名称

对应例程若假设Entry当前包含字符串'abcdefg',用户选择'cde',然后按删除键。这将导致调用isOkay(0,2,'cde'): 0表示删除,2表示'c'之前的位置,'cde'表示要删除的字符串。如果isOkay()返回True,则新文本将为'abfg';如果返回False,则文本不会改变。

invalidcommand:当validatecommand返回值为False,执行由该选项设置的回调函数,其回调函数的设置同validatecommand相同,函数也需要使用register()方法注册。

复选框ttk.Checkbutton

由名字可知就是复选框,类似于考研政治中的多选题。在界面中,可以通过勾选来改变函数的执行之类的配置参数。对于Tkinter,复选框一般有两部分组成,一个是指示器表示状态(类似于选择题的ABCD符号),另一个是标签来展示文本或图片(类似于选择题的选项内容)。

如何获取复选框的勾选情况:

  • 创建一个控制变量,一个IntVar类(和StringVar类型一样是个双向绑定变量,根据名字可知这个表示整数类型)的实例,这样程序就可以查询和设置复选按钮的状态。
  • 使用事件绑定来对checkbutton上的用户动作做出反应

可以禁用复选按钮。这将使其外观变为“灰色”,使其对鼠标没有反应。

在名为parent的顶级窗口或框架中创建一个新的复选框组件:

w = ttk.Checkbutton(parent, option=value, ...)

复选框组件选项:

选项选项介绍
variable跟踪复选按钮当前状态的控制变量,通常在这里使用IntVar,此时off和on值分别为0和1。但是可以使用不同的控制变量类型,并使用该类型的值指定offvalueonvalue选项。
onvalue默认情况下,当复选按钮处于打开 (选中)状态时,关联变量的值为1。您可以使用onvalue选项为打开状态指定一个不同的值。
offvalue默认情况下,当复选按钮处于关闭(未选中)状态时,关联变量的值为0。您可以使用offvalue选项为关闭状态指定一个不同的值。
text显示在复选按钮上的文本,作为字符串。
textvariableStringVar实例,如果设置这个会忽略掉text设置的值,用来动态改变复选按钮上的文本。
image显示在复选按钮上的图像,关于图像在标准属性中有介绍。
compound详情查看关于compound属性
command每当此复选按钮的状态发生变化时调用的函数。
width使用此选项可指定固定宽度或最小宽度。该值以字符指定;正数设置该平均字符的固定宽度,而负数设置最小宽度。
cursor使用此选项指定鼠标光标在组件上方时的外观,在标准属性中有介绍。
underline通过将此选项设置为文本字符串中的某个字母的位置,可以请求将该字母下划线
style使用此选项指定自定义组件样式名称,关于其在自定义和创建主题和样式介绍。
takefocus使用此选项指定在焦点遍历期间是否访问组件,关于其作用在路由键盘输入介绍。
单选框ttk.Radiobutton

相比于复选框,单选框就是单选题了呗。允许用户只选择一组选项中的一个,相同的,单选框也是有两部分组成,指示器和标签。

要将多个单选按钮组成一个互斥组(在组里面只能有一个按钮被选择),需要创建单个控制变量(双向绑定变量 Stringvar或Intvar实例),并将每个单选按钮的variable选项设置为该变量,在互斥组中的按钮必须要有和控制变量相同类型的不同值。

在名为parent的顶级窗口或框架中创建一个新的单选框组件:

w = ttk.Radiobutton(parent, option=value, ...)

单选框组件选项:

选项选项介绍
variable组中其他单选按钮共享的控制变量,该变量的类型需要和组中单选按钮的value选项指定的类型相同。
value与此单选按钮关联的值。当单选按钮在组中被选中时,该选项的值将存储在组的控制变量variable中。
text将以字符串的形式出现在单选按钮旁边。
textvariableStringVar实例,如果设置这个会忽略掉text设置的值,用来动态改变单选按钮上的文本。
image显示在复选按钮上的图像,关于图像在标准属性中有介绍。
compound详情查看关于compound属性
command每当此单选按钮的状态发生变化时调用的函数。
width使用此选项可指定固定宽度或最小宽度。该值以字符指定;正数设置该平均字符的固定宽度,而负数设置最小宽度。
cursor使用此选项指定鼠标光标在组件上方时的外观,在标准属性中有介绍。
underline通过将此选项设置为文本字符串中的某个字母的位置,可以请求将该字母下划线
style使用此选项指定自定义组件样式名称,关于其在自定义和创建主题和样式介绍。
takefocus使用此选项指定在焦点遍历期间是否访问组件,关于其作用在路由键盘输入介绍。
下拉框ttk.Combobox

这个组件是Entry和下拉菜单的组合。在界面中,会有通常的文本输入区域,带有一个向下指向的箭头。当用户单击箭头时,将出现一个下拉菜单。如果用户单击其中一个,则该选项将替换输入框的当前内容。但是,用户仍然可以直接在输入框中输入文本(当输入框组件有焦点时),或者编辑当前文本。

在名为parent的顶级窗口或框架中创建一个新的下拉框组件:

w = ttk.Combobox(parent, option=value, ...)

下拉框组件选项:

选项选项介绍
values传入一个要在下拉菜单中以字符串形式显示的选项列表。例如values=["apple","banana","grape"]
textvariableStringVar实例,绑定出现在Entry区域中的文本
exportselection默认可以在Entry组件中选择文本,自动导出到剪贴板。要避免导出,请使用exportselection=0
validate可以使用此选项设置组件,以便在特定时间由验证函数检查其内容。可查看输入验证
validatecommand验证组件文本的回调,其返回值的bool值若输入检测合规则是true否则为false
xscrollcommand如果组件具有关联的水平滚动条,则将此选项设置为该滚动条的.set方法。可查看横向滚动
postcommand可以使用此选项来提供一个回调函数,当用户单击向下箭头时将调用该函数。这个回调可以改变values选项并显示在下拉菜单中。
width此选项以字符数指定条目区域的宽度。实际宽度将是这个数字乘以有效字体中字符的平均宽度。默认值为20。
height使用此选项可指定将在下拉菜单中显示的最大行数;默认值是20。如果有比这个数字更多的值,下拉菜单将自动包含一个垂直滚动条
justify此选项指定当文本没有完全填满输入区域时,文本将如何在该区域内定位。(tk.LEFTtk.CENTERtk.RIGHT )
cursor使用此选项指定鼠标光标在组件上方时的外观,在标准属性中有介绍。
style使用此选项指定自定义组件样式名称,关于其在自定义和创建主题和样式介绍。
takefocus使用此选项指定在焦点遍历期间是否访问组件,关于其作用在路由键盘输入介绍。
  • 如果组件处于disabled状态,则任何用户操作都不会更改内容。
  • 如果组件处于!disabled状态和readonly状态,则用户可以通过使用下拉菜单更改内容,但不能直接编辑内容。
标签框架ttk.LabelFrame

LabelFrame组件与Frame组件一样,也是一个空间容器——一个可以包含其他组件的矩形区域。但是,与Frame组件不同的是,LabelFrame组件允许您将标签设置在边框上,可以设置通过标签的值来帮助用户理解此区域的功能。

在名为parent的顶级窗口或框架中创建一个新的标签框架组件:

w = ttk.LabelFrame(parent, option=value, ...)

标签框架组件选项:

选项选项介绍
text标签框架的标签内容。
labelanchor使用此选项指定标签在组件边框上的位置。默认位置是'nw'(北西),它将标签放置在上边框的左端。
labelwidget可以使用任何组件作为LabelFrame中的标签,而不是文本标签。创建一个组件w,但不要用.grid()方法注册它。然后使用labelwidget=w创建LabelFrame。如果同时指定此选项和text选项,则会忽略text选项。
height设置组件高度,单位在标准属性中有介绍。若使框架具有设置的高度,使用组件上的.grid_propagate(0)方法。
width设置组件宽度,单位在标准属性中有介绍。若使框架具有设置的宽度,使用组件上的.grid_propagate(0)方法。
underline通过将此选项设置为文本字符串中的某个字母的位置,可以请求将该字母下划线。
cursor使用此选项指定鼠标光标在组件上方时的外观,在标准属性中有介绍,默认继承其父组件的。
relief指定边框的浮雕样式,在标准属性中有介绍。若borderwidth为0,则没有效果。也可以使用style指定此选项。
borderwidth使用此选项可指定边框元素的宽度,默认值为零,单位在标准属性中有介绍。
padding在框架内部和包含的组件外部创建一个空白区域,单位在标准属性中有介绍。例如,padding='0.5c'将填充框架内以及框架内组件的外部半厘米宽的区域。也可以使用style指定此选项。
style使用此选项指定自定义组件样式名称,关于其在自定义和创建主题和样式介绍。
takefocus使用此选项指定在焦点遍历期间是否访问组件,关于其作用在路由键盘输入介绍。
关于labelanchor

在这里插入图片描述

菜单Menu

这个组件并不是来自于ttk模块,而是tkinter原生组件

菜单可以看做是界面功能的集合体,当用户不需要时,只占一部分地方,但用户一点击就可以展示可选的操作。菜单上显示的选项可以是以下内容的任何一个:

  • 一个简单的命令:一个文本字符串(或图像),用户可以选择执行一些操作。
  • 一个下拉框:一个文本字符串(或图像),用户可以选择它来显示另一个完整的选项菜单。
  • 一个多选框
  • 一组单选框

创建一个菜单组件,Menuparent可以是顶级窗口或框架也可以是已有菜单:

w = Menu(Menuparent, option=value, ...)

菜单组件选项:

选项选项介绍
activebackground选择项在鼠标下方时显示的背景颜色。
bgorbackground选择项不在鼠标下方时的背景颜色。
activeborderwidth指定当选择项位于鼠标下方时围绕其绘制的边框的宽度,默认值为1像素。
bdorborderwidth指定地边框宽度,默认值为1像素。
activeforeground选择项在鼠标下方时显示的前景颜色。
fgorforeground选择项不在鼠标下方时的前景颜色。
disabledforeground状态为DISABLED的选项的文本颜色。
font使用此选项可指定显示文本的字体样式,在标准属性中有介绍。
relief指定边框的浮雕样式,在标准属性中有介绍。默认为raised
cursor使用此选项指定鼠标光标在组件上方时的外观,在标准属性中有介绍,但只有当菜单被"撕下"时才会出现。
selectcolor指定选中复选按钮和单选按钮时显示的颜色。
postcommand可以使用此选项来提供一个回调函数,当用户单击按钮时将调用该函数。
tearoff通常,菜单可以被"撕下",选项列表中的第一个位置(位置0)被撕下元素占用,其他选项从位置1开始添加。如果您设置tearoff=0,则菜单将不具有撕扯功能,并且将从位置0开始添加选项。
tearoffcommand如果希望在用户单击菜单中的撕下条目时通知您的程序,请将此选项设置为对应得回调函数。它将用两个参数调用:父窗口的窗口ID和新撕毁菜单根窗口的窗口ID。
title通常,可撕扯菜单窗口的标题将与菜单按钮或指向该菜单的下拉框文本相同。如果想要更改该窗口的标题,可将此选项设置为该标题内容。

菜单组件方法:

方法方法介绍
.add(kind,coption,...)添加给定类型的新元素,作为此菜单中的下一个可用选项。kind参数可以是'cascade''checkbutton''command''radiobutton''separator'中的任何一个。根据类型参数的不同,此方法等价于.add_cascade().add_checkbutton()
.add_cascade(coption,...)添加一个菜单选项,例如一级菜单、二级菜单。使用menu选项连接下级菜单。
.add_checkbutton(coption,...)添加一个复选框选项。
.add_command(coption,...)添加一个新命令选项。使用label、bitmap或image选项将文本或图像放置在菜单上;使用commond选项绑定回调命令。
.add_radiobutton(coption,...)添加一个单选框选项。
.add_separator()添加一个分隔符选项。这只是一条横线,但也算是一个选项。
.delete(index1,index2=None)该方法删除从index1index2(包括index2)编号的选项。要删除一个选项,省略index2参数。
.entrycget(index,coption,...)检索某个菜单选项的某些coption的当前值
.entryconfigure(index,coption,...)更改某个选项的某些coption值,coption=value
.insert_cascade(index,coption,...)插入一个菜单选项
.insert_checkbutton(index,coption,...)插入一个新复选框选项
.insert_command(index,coption,...)插入一个新命令选项
.insert_radiobutton(index,coption,...)插入一个单选框选项。
.insert_separator(index)插入一个分隔符选项。
.invoke(index)执行第index选项相关联的命令回调。如果是复选框选项,则其状态在设置和清除之间切换;如果是单选框选项,则设置该选项。
.post(x,y)在相对于根窗口的位置(x, y)显示此菜单。

菜单组件方法coption内容:

内容内容介绍
accelerator快捷键设置。比如accelerator=’^x’,同时还需要绑定键盘输入,才能实现快捷键的功能。
activebackground选项在鼠标下方时使用的背景颜色。
background当选项不在鼠标下方时使用的背景颜色。
activeforeground选项在鼠标下方时使用的前景颜色。
foreground选项不在鼠标下方时使用的前景色。
label显示文本字符串。
image显示图像,关于图像在标准属性中有介绍。
bitmap显示此选项的位图。
compound详情查看关于compound属性
command菜单选项的回调函数。
font使用此选项可指定显示文本的字体样式,在标准属性中有介绍。
state通常,所有选择都对鼠标单击作出反应,但是您可以设置state=tk.disable,使其无响应。
hidemargin默认情况下,一个小的边距分隔菜单中相邻的选项,使用hidemargin=True来隐藏此边距。
columnbreak在新的一列开始显示菜单选项。
underline通常标签上的字母都没有下划线。将此选项设置为字母的索引,以便在该字母下划线
menu此选项仅用于cascade操作。将其设置为显示下一级选择的Menu对象。
variable对于复选按钮或单选按钮,应该将该选项设置为与复选按钮或单选按钮组相关联的控制变量。
onvalue当复选选项处于打开状态时,复选选项的variable被设置为1。可以通过将此选项设置为所需值。
offvalue当复选选项处于关闭状态时,复选选项的variable被设置为0。可以通过将此选项设置为所需值。
value指定单选选项的关联控制变量的值
selectcolor复选按钮或单选按钮中显示的颜色为红色,可以用此更改该颜色。
selectimage可以设定选中的情况下,使用image作为提示信息

参考:Python tkinter-- 第16章 菜单(Menu)菜单项选项_offvalue-CSDN博客

创建顶级菜单
from tkinter import *
from tkinter import ttk

def menucallback():
    print("hello")
    
root = Tk()
mainMenu = Menu(root, tearoff=False)
mainMenu.add_command(label="test1", command=menucallback)
mainMenu.add_separator()
mainMenu.add_command(label="test2")
root["menu"] = mainMenu
root.mainloop()

运行效果:

在这里插入图片描述

创建下拉菜单
from tkinter import *
from tkinter import ttk

def menucallback():
    print("hello")
    
root = Tk()
mainMenu = Menu(root, tearoff=False)
testMenu = Menu(mainMenu)

testMenu.add_command(label="test1", command=menucallback)
testMenu.add_separator()
testMenu.add_command(label="test2")

mainMenu.add_cascade(label="test", menu=testMenu)

root["menu"] = mainMenu
root.mainloop()

运行效果:

在这里插入图片描述

创建弹出菜单
from tkinter import *
from tkinter import ttk

def show(event):
    mainMenu.post(event.x_root, event.y_root)
   
def menucallback():
    print("hello")
    
root = Tk()
mainMenu = Menu(root, tearoff=False)
testMenu = Menu(mainMenu)

testMenu.add_command(label="test1", command=menucallback)
testMenu.add_separator()
testMenu.add_command(label="test2")

mainMenu.add_cascade(label="test", menu=testMenu)

#当用户点击鼠标右键时
root.bind("<Button-3>", show)
root.mainloop()

运行效果:

在这里插入图片描述

菜单按钮ttk.MenuButton

Menubutton 组件是一个与 Menu 组件相关联的按钮,它可以放在窗口中的任意位置,并且在被按下时弹出下拉菜单。

在名为parent的顶级窗口或框架中创建一个新的菜单按钮组件:

w = ttk.Menubutton(parent, option=value, ...)

菜单按钮组件选项:

选项选项介绍
menu设置相关的Menu组件
direction此选项指定下拉菜单相对于菜单按钮出现的位置。
text菜单按钮的标签内容。
textvariable菜单按钮文本的控制变量
image显示图像,关于图像在标准属性中有介绍。
compound详情查看关于compound属性
underline如果此选项具有非负值n,则将在位置n处的字符下方显示下划线。
cursor使用此选项指定鼠标光标在组件上方时的外观,在标准属性中有介绍。
width如果标签是文本,则此选项指定按钮上文本区域的绝对宽度,以字符数表示;实际宽度是该数字乘以当前字体中字符的平均宽度。对于图像标签,此选项将被忽略。
style使用此选项指定自定义组件样式名称,关于其在自定义和创建主题和样式介绍。
takefocus使用此选项指定在焦点遍历期间是否访问组件,关于其作用在路由键盘输入介绍。

关于direction

  • above:菜单将出现在菜单按钮的上方。
  • below:菜单将出现在菜单按钮的下方,默认值。
  • flush:菜单将出现在菜单按钮的上方,菜单的右上角与菜单按钮的右上角重合。
  • left:菜单将出现在菜单按钮的左方。
  • right:菜单将出现在菜单按钮的右方。
from tkinter import *
from tkinter import ttk
   
def menucallback():
    print("hello")
    
root = Tk()
mainMenu = Menu(root, tearoff=False)
testMenu = Menu(mainMenu)

mainMenu.add_cascade(label="test", menu=testMenu)
testMenu.add_command(label="test1", command=menucallback)
testMenu.add_separator()
testMenu.add_command(label="test2")

ttk.Menubutton(root, text="clickme", menu=mainMenu, direction="above").pack()
root.mainloop()

运行效果:

在这里插入图片描述

选项卡ttk.Notebook

该组件的目的是提供一个区域,用户可以通过单击该区域顶部的选项卡来选择内容页面。

  • 每当用户单击其中一个选项卡时,组件将显示与该选项卡关联的子窗格。通常,每个窗格将是一个Frame组件,当然窗格也可以是别的组件。
  • 当前显示的子窗格的选项卡称为选定选项卡。
  • 使用Notebook组件的.add()方法附加一个新选项卡及其相关内容。其他方法允许删除或临时隐藏选项卡。
  • 这个组件的许多方法使用tabId的概念来引用其中一个选项卡。tabId的不同值可以是:
    • 整数值指的是选项卡的位置:第一个选项卡为0,第二个选项卡为1,依此类推。
    • 可以通过使用子部件本身来引用选项卡。
    • "@x,y"形式的字符串指向当前包含相对于组件的点(x,y)的选项卡。例如,字符串“@37,0”沿着选项卡的上边缘将指定选项卡包含距离组件左侧37像素的点。
    • 字符串“current”指的是当前选择的选项卡。
    • 在调用组件的.index()方法时,使用字符串“end”确定当前显示的选项卡数量。

在名为parent的顶级窗口或框架中创建一个新的选项卡组件:

w = ttk.Notebook(parent, option=value, ...)

选项卡组件选项:

选项选项介绍
width分配给组件的宽度(以像素为单位)。
height分配给组件的高度(以像素为单位)。
padding要在组件的外部添加一些额外的空间。
cursor使用此选项指定鼠标光标在组件上方时的外观,在标准属性中有介绍。
style使用此选项指定自定义组件样式名称,关于其在自定义和创建主题和样式介绍。
takefocus使用此选项指定在焦点遍历期间是否访问组件,关于其作用在路由键盘输入介绍。

选项卡组件方法:

方法方法介绍
.add(child,**kw)child参数是一个组件,通常是Frame,用于包装一个子窗格的内容。如果child不是Notebook组件的子窗格之一,则将child添加为下一个可用的选项卡,关键字参数kw定义新窗格的选项卡选项。如果child是当前隐藏的窗格,则该选项卡将重新出现在其原来的位置。
.enable_traversal()一旦你调用了这个方法,一些额外的键绑定将会起作用
.forget(child)此方法永久地从组件的选项卡删除指定的子组件。
.hide(tabId)tabId标识的选项卡将暂时从Notebook中的可见选项卡删除。可以通过再次调用.add()方法来恢复它。
.index(tabId)对于给定的tabId,此方法返回相应tab的数字索引。有一个例外:如果参数是字符串"end",该方法将返回选项卡的总数。
.insert(where,child,**kw)此方法将组件子部件插入到where指定的位置,"end"将新选项卡放置在所有现有选项卡之后;若是现有的子部件,新子组件插入到现有组件的前面。后俩参数和add()相同
.select([tabid])如果不带参数调用此方法,它将返回当前显示其选项卡的组件的窗口名称。要在Notebook中显示特定的窗格,请使用tabId作为参数调用此方法。
.tab(tabid,option=None,**kw)使用此方法可以为tabId对应的子窗格设置选项卡选项,或者查找为该子窗格设置了哪些选项。如果不带关键字参数调用该方法,它将返回当前对tagId指定的窗格有效的选项卡选项的字典。要找出特定选项X的当前值,使用参数“option=X”调用此方法,该方法将返回该选项的值。或者使用参数“X=Value”调用此方法来设置该选项的值。
.tabs()此方法按顺序返回Notebook子窗格的窗口名称列表。

关于add、insert、tab的选项配置

  • compound:详情查看关于compound属性
  • padding:使用此选项可以在面板内容的四面周围添加额外的空间
  • sticky:详情查看Grid方法
  • image:若要在选项卡上显示图形图像,请提供图像作为此选项的值。关于图像在标准属性中有介绍。
  • text:要显示在选项卡上的文本。
  • underline:如果此选项具有非负值n,则将在选项卡上文本的第n位置的字符下方显示下划线。

关于enable_traversal

  • Ctrl-Tab将选择当前选中的选项卡后的选项卡。如果当前选择了最后一个选项卡,则选择将旋转回第一个选项卡。
  • Shift-Ctrl-Tab则相反:它移动到前一个选项卡,如果选择了第一个选项卡,则绕到最后一个选项卡。
  • 可以配置一个特定的热键,直接选择选项卡。为此,使用文本和下划线选项卡为每个选项卡中的一个字符加下划线。然后用户可以通过键入Alt-x跳转到一个选项卡,其中x是该选项卡上带下划线的字符。
from tkinter import *
from tkinter import ttk
   
root = Tk()
notebook = ttk.Notebook(root)

# 可以看到对于选项卡窗格中的组件 无需传递其父组件
frame1 = ttk.Frame(width=100, height=100, relief="groove")
frame1.grid_propagate(0)
ttk.Label(frame1, text="测试1", background="#ff0").grid()

frame2 = ttk.Frame(width=100, height=100, relief="groove")
frame2.grid_propagate(0)
ttk.Label(frame2, text="测试2", background="#f0f").grid()

# 这里使用Alt+a就可以选择第一个选项卡 无需添加按键绑定事件
notebook.add(frame1, text='a选项卡1', underline=0)
notebook.add(frame2, text='选项卡2')

notebook.pack()
notebook.enable_traversal()

root.mainloop()

运行效果:

在这里插入图片描述

分块窗口ttk.PanedWindow

Frame组件类似也是个空间管理组件,但是不同于Frame内的组件都是依靠空间几何管理方法(pack grid place),该组件采取分块的方式,无需以上管理方法,且用户可以自由调整各区域分块大小。

在名为parent的顶级窗口或框架中创建一个新的分块窗口组件:

w = ttk.PanedWindow(parent, option=value, ...)

分块窗口组件选项:

选项选项介绍
width分配给组件的宽度。
height分配给组件的高度。
orientHORIZONTAL组件水平排放;VERTICAL 默认值 组件竖直排放。
cursor使用此选项指定鼠标光标在组件上方时的外观,在标准属性中有介绍。
style使用此选项指定自定义组件样式名称,关于其在自定义和创建主题和样式介绍。
takefocus使用此选项指定在焦点遍历期间是否访问组件,关于其作用在路由键盘输入介绍。

分块窗口组件方法:

方法方法介绍
.add(w[, weight=N])向窗口添加一个新窗格,其中w是任何组件(但通常是Frame)。如果提供weight选项,它将描述相对于其他窗格的堆叠维度窗格的大小。
.forget(what)移除窗格。参数可以是窗格的索引(从零开始计数),也可以是子组件。
.insert(where, w[, weight=N])where指定的位置向窗口添加新窗格w, where可以是索引,也可以是要在其之前插入新窗格的窗格组件
.panes()此方法返回PanedWindow的子部件列表。
from tkinter import *
from tkinter import ttk
   
root = Tk()
pw = ttk.Panedwindow(root, orient=VERTICAL)
pw.pack(fill=BOTH, expand=1)

labal1 = ttk.Label(pw, text="labal1", background='green')
pw.add(labal1)

pw1 = ttk.Panedwindow(pw, orient=HORIZONTAL)
pw.add(pw1)

labal2 = ttk.Label(pw1, text="labal2", background='red')
pw1.add(labal2)

labal3 = ttk.Label(pw1, text="labal3", background='blue')
pw1.add(labal3)

root.mainloop()

运行效果:

在这里插入图片描述

进度条ttk.Progressbar

这个组件的目的是向用户保证正在发生某些事情。它可以在两种模式下工作:

  • 在确定模式下,组件显示一个在程序控制下从开始到结束移动的指示器。
  • 在不确定模式下,组件是动画的,这样用户就会认为正在进行某些操作。在此模式下,指示器在组件的两端来回弹跳。

在名为parent的顶级窗口或框架中创建一个新的进度条组件:

w = ttk.Progressbar(parent, option=value, ...)

进度条组件选项:

选项选项介绍
length组件沿其方向的长度。
maximum指标的最大值;默认值是100。
modeindeterminate:不确定模式 使用.start()方法后,矩形会在组件的两端来回弹跳。determinate:确定模式,就是常规下载进度条。
orientHORIZONTAL 默认值 方向水平;VERTICAL 方向竖直。
variable使用控制变量,以便可以获取或设置指示器的当前值。
cursor使用此选项指定鼠标光标在组件上方时的外观,在标准属性中有介绍。
style使用此选项指定自定义组件样式名称,关于其在自定义和创建主题和样式介绍。
takefocus使用此选项指定在焦点遍历期间是否访问组件,关于其作用在路由键盘输入介绍。

进度条组件方法:

方法方法介绍
.start([interval])每隔几毫秒开始移动指示器;默认值是50ms。每次都像调用.step()方法一样移动指示符。。
.step([delta])这种方法使指标值以增量增加;默认增量为1.0。在确定模式下,指示器将永远不会超过最大选项的值。在不确定模式下,当指示器达到最大值时,指示灯将倒转方向并开始倒计时。
.stop()暂停进度条。

参考Python之tkinter 进度条 Progressbar-CSDN博客

刻度条ttk.Scale

允许用户在指定范围内设置一些intfloat值。

  • 可以使用鼠标拖动滑块
  • 也可以直接点击滑块轨迹,滑块会自动移过去。
  • 也可以绑定键盘事件设置刻度条。

在名为parent的顶级窗口或框架中创建一个新的刻度条组件:

w = ttk.Progressbar(parent, option=value, ...)

刻度条组件选项:

选项选项介绍
length组件沿其方向的长度。
from_to选项结合使用,以将值约束到一个数字范围。例如,from_=-10和to=10只允许−1020之间的值。
tofrom_结合使用 设置进度条范围。
command每当此组件的状态发生变化时调用的函数。该函数将接收一个参数,即组件上显示的新值,类型为浮点数。
orientHORIZONTAL 默认值 方向水平;VERTICAL 方向竖直。
value使用此选项设置组件变量的初始值;默认值是0.0
variable使用控制变量,以便可以获取或设置刻度条的当前值。整型就绑定IntVar,浮点型就绑定DoubleVar
cursor使用此选项指定鼠标光标在组件上方时的外观,在标准属性中有介绍。
style使用此选项指定自定义组件样式名称,关于其在自定义和创建主题和样式介绍。
takefocus使用此选项指定在焦点遍历期间是否访问组件,关于其作用在路由键盘输入介绍。
滚动条ttk.Scrollbar

用于滚动一些组件的可见范围,根据方向可分为垂直滚动条和水平滚动条。组件常常被用于实现文本、画布和列表框的滚动。

在名为parent的顶级窗口或框架中创建一个新的滚动条组件:

w = ttk.Scrollbar(parent, option=value, ...)

滚动条组件选项:

选项选项介绍
command每当滚动条开始移动调用的函数。
orientHORIZONTAL 默认值 方向水平;VERTICAL 方向竖直。
cursor使用此选项指定鼠标光标在组件上方时的外观,在标准属性中有介绍。
style使用此选项指定自定义组件样式名称,关于其在自定义和创建主题和样式介绍。
takefocus使用此选项指定在焦点遍历期间是否访问组件,关于其作用在路由键盘输入介绍。
关于如何调用函数的参数

当用户操作滚动条时,滚动条调用它的命令回调。此调用的参数取决于用户的操作:

  • 当用户请求向左或向上移动一个“单位”时,回调的参数为

    command(tk.SCROLL, -1, tk.UNITS)
    
  • 当用户请求向右或向下移动一个“单位”时,回调的参数为

    command(tk.SCROLL, 1, tk.UNITS)
    
  • 当用户请求向左或向上移动一"页"时,回调的参数为

    command(tk.SCROLL, -1, tk.PAGES)
    
  • 当用户请求向右或向下移动一"页"时,回调的参数为

    command(tk.SCROLL, 1, tk.PAGES)
    
分割符ttk.Separator

使用此组件放置分隔其他组件的水平或垂直条,组件呈现为2像素宽的线。确保使用.grid()方法的sticky选项来拉伸组件,否则它将仅显示为单个像素。

在名为parent的顶级窗口或框架中创建一个新的分割符组件:

w = ttk.Separator(parent, option=value, ...)

分割符组件选项:

选项选项介绍
orientHORIZONTAL 默认值 方向水平;VERTICAL 方向竖直。
style使用此选项指定自定义组件样式名称,关于其在自定义和创建主题和样式介绍。

通用组件方法

就是组件的信息。这里只列举了几个常用的,更多可参考26. Universal widget methods (tkdocs.com)

方法内容
w.after(delay_ms,callback=None,*args)在经过delay_ms时长后,执行回调函数,一次性。返回一个整数“after identifier”,如果想取消回调,这个整数可以传递给.after_cancel()方法。若没设置回调函数,相当于延时函数。
w.after_cancel(id)取消先前设置的回调请求.after()
w.after_idle(func,*args)请求下次系统空闲时,也就是说,下次没有事件要处理时,使用参数调用函数func。也是一次性的。
w.bell()组件发出响声,win10会叮咚一下。
w.bind(sequence=None, func=None, add=None)此方法用于将事件绑定附加到组件。
w.bind_all(sequence=None, func=None, add=None)类似于.bind(),但适用于整个界面中的所有组件。
w.bind_class(className,sequence=None, func=None, add=None)类似于.bind(),但适用于所有名为className的组件(例如,'Button')。
w.destroy() 摧毁组件以及子组件。
w.quit() 此方法退出主循环。
组件的信息言简意赅,比如组件它爹是谁,它有没有儿子,多高多宽了。
winfo_class标识组件类型的类,例如,TButton表示主题按钮。
winfo_children作为层次结构中某个组件的子组件的列表。
winfo_parent组件在层次结构中的父级。
winfo_toplevel包含此组件的顶层窗口。
winfo_width, winfo_height组件的当前宽度和高度;直到它出现在屏幕上才算准确。
winfo_reqwidth, winfo_reqheight组件向几何管理器请求的宽度和高度(稍后会详细介绍)。
winfo_x, winfo_y组件的左上角相对于其父部件的位置。
winfo_rootx, winfo_rooty组件的左上角相对于整个屏幕的位置。
winfo_vieweable组件是显示还是隐藏(要使它可见,它在层次结构中的所有祖先必须是可见的)。

其中对于组件申请的宽高由于几何管理的调整,和实际宽高并不一定相同,所以关于宽高信息有两个

组件状态

控件状态是多个相互独立的状态标志位的组合。

状态描述
active鼠标光标经过控件并按下鼠标按钮,将引发动作。
disabled控件处于禁用状态,而由程序控制。
focus控件接受键盘焦点。
pressed控件已被按下。
selected勾选或单选框之类的控件,表示启用、选中状态。
backgroundWindows 和 Mac 系统的窗口具有“激活”或后台的概念。后台窗口的控件会设置 foreground 参数,而前台窗口的控件则会清除此状态。
readonly控件不允许用户修改。
alternate控件的备选显式格式。
invalid控件的值是无效的
w.state(['disabled'])        	  	# 设置为disabled状态
w.state(['!disabled'])        		# 清除disabled状态
w.instate(['disabled'])        		# 如果是disabled状态 返回true 否则返回false
w.instate(['!disabled'])       		# 如果不是disabled状态 返回true 否则返回false
w.instate(['!disabled'], callback)  # 若判断的结果为true 执行callback函数

组件自定义样式

就像前端设计一样,给每个标签打上class,然后在CSS中自定义该类的样式。Tkinter也有相同的操作,只不过在这里不是class而是style,而关于样式的命名,不是随心所欲起名,而是有一定的限制。

  • theme是一个完整的“外观”,自定义所有组件的外观。风格可以控制所有组件的样式,像QQ中个人装扮的主题,通过修改什么聊天背景了、聊天气泡了、聊天字体了都会发生变化,不只是单单的设计其中一个。
  • style是对一种组件外观的描述。每个theme都有一组预定义的样式,但也可以自定义内置样式或创建一个新样式。与风格相对比,这个只是单单的修改一项。
查找和使用ttk主题

查找

from tkinter import ttk
s = ttk.Style()
# 会返回一个主题元组
s.theme_names()
# ('winnative', 'clam', 'alt', 'default', 'classic', 'vista', 'xpnative')

使用

from tkinter import ttk
s = ttk.Style()
# 无参会返回当前使用的主题
s.theme_use()
# 带参是使用新的主题
s.theme_use('winnative')
使用和自定义ttk样式

对于任何组件都有一个样式,而这个样式是在所选主题中早已定义好的。

  • 每一个组件都有其对应的默认样式名称,通常在其组件名前加一个'T'。例如Button按键组件所使用的样式名为TButton

    不规则命名组件

    组件组件样式名
    PanedWindowTPanedwindow而不是TPanedWindow
    ProgressbarHorizontal.TProgressbarVertical.TProgressbar 取决于orient选项
    ScaleHorizontal.TScaleVertical.TScale取决于orient选项
    ScrollbarHorizontal.TScrollbarVertical.TScrollbar取决于orient选项
  • 相比于默认样式名称,用户也可以自定义样式。虽然是自定义,名字也不能随便取。要采取newname.oldname的形式,其中oldname是原先组件的样式即上面所说的默认样式名称,newname就可以随便起名字了。例如对于按键组件,我想自定义一个它的样式我起名必须是xx.TButton。其中设置样式属性会覆盖默认自带属性,若是没涉及的则使用整体风格中按键所默认的。同理,也可以起名为new2name.new1name.oldname

  • 特殊的有一个名为'.'的根样式。可以更改每个组件的样式。

使用.configure()方法来更改样式,因为theme原先就带自己的样式。

#先实例化当前风格样式
s = ttk.Style()

# 默认样式就是 style="TButton"
ttk.button(parent,text="默认样式").pack()
ttk.button(parent,text="自定义样式",style="green.TButton").pack()
ttk.Label(parent,text="全局样式").pack()

#现在该界面中已经有三个组件 分别是一个使用默认样式的按键、自定义样式的按键、默认样式的标签
#更改默认样式的文本颜色 为红色
s.configure('TButton', foreground='red')
#更改自定义样式的文本颜色 为绿色
s.configure('green.TButton', foreground='green')
#更改全局样式的文本颜色 为蓝色
s.configure('.', foreground='blue')
动态样式变化

每个组件在特定事件下都有不同的状态,可以通过设置使组件在不同状态下都有不同的样式。

使用.map(styleName, *p, **kw)方法来查看并更改动态样式

  • 查看

    changes = s.map('TButton', 'foreground')
    #可能的输出 [('pressed', '#ececec'), ('active', '#4a6984')]
    #表面在按下和正常状态的前景文本颜色
    
  • 设置

    s = ttk.Style()
    s.configure('TButton',
                background='black',
                foreground='white',
                highlightthickness='20',
                font=('Helvetica', 18, 'bold'))
    s.map('TButton',
          foreground=[('disabled', 'yellow'),
                      ('pressed', 'red'),
                      ('active', 'blue')],
          background=[('disabled', 'magenta'),
                      ('pressed', '!focus', 'cyan'),
                      ('active', 'green')],
          highlightcolor=[('focus', 'green'),
                          ('!focus', 'red')],
          relief=[('pressed', 'groove'),
                  ('!pressed', 'ridge')])
    
    • 此按钮最初将在黑色背景上显示白色文本,并以20像素宽的焦点高亮显示。
    • 如果按钮处于disabled状态,它将在品红背景上显示黄色文本。
    • 如果当前按钮被按下,文本将显示为红色;如果按钮没有焦点,背景将是cyan的。元组('pressed','!Focus','cyan”)就是一个例子,说明如何使属性依赖于状态的组合。
    • 如果按钮处于active 状态(在光标下),则文本将在绿色背景上显示为蓝色。
    • 当按钮有焦点时,焦点突出显示为绿色,当按钮没有焦点时,焦点突出显示为红色。
    • 按钮未按下时显示groove relief,按下时显示ridge relief

双向绑定数据(控制变量)

Tkinter控制变量是一种特殊的对象,其作用类似于普通的Python变量,因为它是值(如数字或字符串)的容器。

控制变量的一个特殊特性是它可以被许多不同的组件共享,并且控制变量可以记住当前正在共享它的所有组件。这意味着,如果程序用c.set(v)方法将值v存储到控制变量c中,任何链接到该控制变量的组件都会在屏幕上自动更新。同理如果用户在界面中对绑定控制变量的组件进行操作,比如输入框输入了内容,多选框进行了勾选,绑定的控制变量也会发生变化。

Tkinter在许多重要的组件中使用控制变量,例如:

  • Checkbutton使用控制变量来保持复选按钮的当前状态(开或关)。
  • 单个控制变量由一组Radiobutton共享,可用于说明当前设置了其中的哪一个。当用户单击组中的一个单选按钮时,组中任何其他设置的单选按钮都将被清除。在一个组的充要条件是组内按钮绑定一个控制变量,且组内按钮值不同。
  • 控制变量可用来保存文本字符串。通常,Entry组件中显示的文本链接到一个控制变量。在其他几个控件中,可以使用字符串值的控件变量来保存文本,例如CheckbuttonRadiobutton的标签以及Label组件的内容。

要获得控制变量,根据需要在其中存储的值的类型,使用以下类构造函数之一:

v = tk.DoubleVar()   # Holds a float; default value 0.0
v = tk.IntVar()      # Holds an int; default value 0
v = tk.StringVar()   # Holds a string; default value ''
# v = tk.IntVar(1) 默认值就是1了

所有的控制变量只有两个方法

.get():返回变量的当前值

.set():更改变量的当前值。如果任何组件选项从属于这个变量,这些组件将在主循环下一次空闲时更新

焦点获取:路由键盘输入

说一个组件具有焦点意味着键盘输入当前被定向到该组件。

焦点遍历,指的是当用户使用tab键从一个组件移动到另一个组件时将访问的组件序列。

  • 可以使用shift-tab键向后遍历
  • Entry组件旨在接受键盘输入,如果当前具有焦点,键入的任何字符都将添加到其文本中。
  • 大多数其他类型的组件通常会被焦点遍历访问,当它们有焦点时:
    • Button组件可以通过按空格键来“pressed”
    • Checkbutton 组件可以使用空格键在设置和清除状态之间切换。
    • Radiobutton 组件可以使用空格键设置。
    • 水平Scale组件响应←和→键,垂直Scale组件响应↑和↓键。
    • Scrollbar组件中,PageUp和PageDown键通过页面加载来移动滚动条。↑和↓键将按单位移动垂直滚动条,←和→键将按单位移动水平滚动条。
  • 许多组件都提供了一个称为焦点突出显示的轮廓,它向用户显示哪个组件具有突出显示。这通常是一个位于组件边界(如果有的话)之外的黑色细框。对于通常不具有焦点突出显示的组件(特别是frame、label和menu),可以将highlightthickness选项设置为非零值,以使焦点突出显示可见。
  • 可以使用highlightcolor选项更改焦点突出显示的颜色。
  • 焦点通常不会访问FrameLabelMenu类的组件。但是可以将它们的takefocus选项设置为1,以便将它们包含在焦点遍历中。还可以通过将任何组件的takefocus选项设置为0,使其脱离焦点遍历。

tab键遍历组件的顺序如下:

  • 对于属于同一父组件的子组件,焦点按照组件创建的顺序进行。
  • 对于包含其他组件(如frame)的父组件,焦点首先访问父组件(除非它的takefocus选项为0),然后它将按照创建的顺序递归地访问子组件。

🔧几何管理

在Tkinter中关于几何管理有三种方式,都是控制组件如何在窗口中布局的。当创建一个组件时,他们就像前文所说的,并不会在界面出现,只有向几何管理器注册之后才可以。尽管有三种方式进行几何管理,但最常用的且Tkinter作者强烈推荐的是grid()方法,所以也重点介绍该管理器

Grid方法

该几何管理器将每个窗口或框架视为一张表——由行和列组成的表格,可以想象在操作一个excel文件

  • 单元格是一行和一列相交处的面积

  • 每列的宽度取决于该列最宽单元格的宽度,每行的高度取决于该列最高单元格的高度

  • 对于没有填满的整个单元格的部件,可以指定如何处理

    • 直接拉伸组件 使其填满整个单元格
    • 调整其在单元格中的位置 例如靠左还是靠右
  • 单元格也可以合并,变成一个更大的单元格

使用方法:

# 创造一个组件 当然不限于labal组件
widget = tk.Labal(parent, ...)
# 使用grid在几何管理器中注册该组件 对于每个组件都会有这个方法 因为可以看到关于组件对象继承图 其父类之一就是tkinter.Grid
widget.grid(option=value, ...)

可知,对于组件的创造过程都需要传入一个父组件参数,大多数都是Frame组件,而当使用grid管理组件的时候,管理的布局面积是其父类的整个空间。就像所说的对组件的几何管理,就像室内设计,其中每个家具在那一层在创建的时候就固定了,不可能你家的冰箱一设计突然跑到楼上楼下去了。

配置参数:

参数参数介绍
row,column要对组件进行网格化的行、列号,从0开始计数。默认值为零
rowspan,columnspan将多个单元格合并为一个更大的单元格。例如,w.grid(row=0, column=2, rowspan=3)将把组件w放在跨越第第0、1和2行2列中的单元格中,columnspan同理。
ipadx,ipady内部x填充,添加到组件的左右两侧。内部y填充,添加到组件的上下两侧。
padx,pady外部x填充,添加到组件的左边和右边。外部y填充,添加到组件的上方和下方。
sticky如何分配单元格中未被组件占用的额外空间。

关于sticky,布局就像地图上北下南,左西右东

  • 如果没有设置其参数,组件默认置于单元格的中心。
  • 可用参数 tkinter.N 中心靠上, tkinter.E 中心靠右, tkinter.S 中心靠下, tkinter.W 中心靠左, tkinter.NE 右上, tkinter.SE 右下, tkinter.NW 左上, tkinter.SW 左下,英语和地理基础好一点应该挺清楚的。
  • 对于单方向也可以使用元组进行组合
    • 使用tkinter.N+tkinter.S垂直拉伸组件,但保持其水平居中。
    • 使用tkinter.E+tkinter.W水平拉伸组件,但保持其垂直居中。
    • 使用tkinter.N+tkinter.E+tkinter.S+tkinter.W来水平和垂直拉伸组件以填充单元格。
    • 其他组合也可以。例如:使用tkinter.N+tkinter.S+tkinter.W将垂直拉伸组件,并将其放置在西(左)侧。

配置行列尺寸

若没有采取一些措施,网格列的宽度将等于其最宽单元格的宽度,网格行的高度将等于其最高单元格的高度。组件上的sticky属性仅在它没有完全填充单元格的情况下才能控制它的放置位置。

若想手动调整列和行的大小,可以在包含网格布局的父组件(一般是框架)上使用这些方法

  • w.columnconfigure(N, option=value, ...)

    配置列N,使给定选项具有给定值。

  • w.rowconfigure(N, option=value, ...)

    配置行N,使给定选项具有给定值

可选配置选项:

选项选项介绍
minsize列或行以像素为单位的最小尺寸。
pad添加到给定列或行上的像素数。
weight若要使列或行可拉伸,请使用此选项并提供一个值,该值在分配额外空间时给出该列或行的相对权重。

关于weight的使用可查看此链接

📃事件处理

界面不像图片一样,只是一个模板,数据都是固定的。它最大的一个特征就是与用户进行交互,没有交互的界面就是不是一个好的GUI程序,事件是发生在界面上的事情(例如,用户按下一个键、单击或拖动鼠标),界面需要对这些事件作出反应。

一般来说,Tkinter管理这个事件循环。它将找出该事件适用于哪个组件(用户是否单击了此按钮?如果按了一个键,哪个文本框有焦点?),并相应地调度它。单个组件知道如何响应事件;例如,当鼠标移动到按钮上时,按钮可能会改变颜色,当鼠标离开按钮时,按钮可能会恢复原样。

因为关于这些交互都是采用事件-回调函数的方式实现,所以在事件驱动的界面中,事件循环不被阻塞是至关重要的。事件循环应该连续运行,通常每秒执行几十个步骤。在每一步中,它都会处理一个事件。如果某个回调函数需要执行长时间的操作,它可能会阻塞事件循环。在这种情况下,不会处理任何事件,不会完成任何绘图,并且看起来好像界面被冻结了。当然可以采用线程方式来避免出现这样的情况

绑定级别

可以在三个层次上绑定一个事件的处理程序

  1. 实例绑定:.bind()方法可以将事件绑定到一个特定的组件实例。例如,可以将鼠标中键按下绑定一个按钮按下的处理程序。

    def click(e):
        print("click me")
    btn = ttk.Button(parent,commond=click)
    btn.bind('<Button-2>', click)
    
  2. 类绑定:.bind_class()方法可以将事件绑定到一个特定的组件类。例如,可以将鼠标中键按下绑定所有按钮按下的处理程序。

    def click(e):
        print("click me")
    btn = ttk.Button(parent,commond=click)
    btn.bind_class('Button','<Button-2>',click)
    
  3. 界面绑定:.bind_all()方法可以绑定一个界面,而不管哪个组件有焦点或在鼠标下方。

    def click(e):
        print("click me")
    btn = ttk.Button(parent,commond=click)
    btn.bind_all('<Button-2>',click)
    

事件描述

#事件表达的一般形式
<[modifier-]...type[-detail]>
  • 所有的事件都要在<...>其中描述
  • type表达一般的事件,例如按键或鼠标点击。稍后介绍
  • modifier可以在类型之前添加可选的修饰项,以指定组合,例如在按其他键或单击鼠标时按下shift键或Control(ctrl)键。
  • detail可以添加可选的细节项来描述正在寻找的键或鼠标按钮。对于鼠标按钮,1表示左键,2表示按钮中键,3表示按钮右键。

例如:

例子例子内容
<Button-1>用户按下鼠标的左键
<KeyPress-H>用户按下键盘的H
<Control-Shift-KeyPress-H>用户按下键盘的组合键键ctrl-shift-H
事件类型type

完整的事件类型集合相当大,但其中很多都不常用。以下是比较需要的:

类型类型内容
Button用户按下了一个鼠标按钮,detail指定了哪个按钮。
ButtonRelease用户松开鼠标按钮。在大多数情况下,这可能是比Button事件更好的选择,因为如果用户不小心按下按钮,他们可以将鼠标移离组件以避免触发事件。
Motion用户在组件内完全移动鼠标指针。
MouseWheel用户向上或向下移动鼠标滚轮。对Linux无效
KeyPress用户按下键盘上的一个键。detail指定了哪个键。该关键字可以缩写为Key
KeyRelease用户释放了一个键。
Activate组件从非活动状态变为活动状态。这指的是组件state选项的更改。
Deactivate组件从活动状态变为非活动状态。这指的是组件state选项的更改。
Configure用户更改组件的大小,例如通过拖动窗口的一角或一侧。
Destroy一个组件正在被销毁。
Enter用户将鼠标指针移动到组件的可见部分。(这与enter键不同,enter键是一个KeyPress事件,其名称实际上是'return'。)
Leave用户将鼠标指针移出组件。
FocusIn一个组件获得了输入焦点
FocusOut输入焦点移出了组件。
Map正在映射一个组件,使其在界面中可见。例如调用组件的.grid()方法时,就会发生这种情况。
Unmap一个组件正在被取消映射并且不再可见。例如使用组件的.grid_remove()方法时,就会发生这种情况。
事件修饰modifier
修饰修饰内容
Alt当用户按住alt
Control当用户按住ctrl
Shift当用户按住Shift
Any全事件类型。例如'<any-keypress>'适用于按下任何键。
Double双击,例如<Double-Button-1>表示快速连续按两次鼠标左键。
Triple三连击

可以使用事件的缩写形式:

  • '<1>''<Button-1>'相同。
  • 'x''<KeyPress-x>'相同。

对于更多的键盘映射内容请参考54.5. Key names (tkdocs.com)

对于大多数单字符按键,可以省略封闭的'<…>',但是对于空格字符(其名称为'<space>')或小于(<)字符(其名称为'<less>')不能这样做。

事件回调函数参数

def callback(event):
    ...

对于event,当绑定事件执行后,会调用绑定的回调函数,其中会传递一个参数来表明这次事件触发的内容。

其中一些属性总是设置的,但有些属性只针对某些类型的事件设置。

属性属性内容
.widget始终设置为引起事件的小部件。
.type描述事件类型的数字代码。有关此代码的解释Section 54.3, “Event types”.
.char如果事件与产生常规ASCII字符的键的KeyPressKeyRelease相关,则此字符串将被设置为该字符。(对于像delete这样的特殊键,请参阅下面的.keysym属性。)
.keycode对于KeyPressKeyRelease事件,该属性被设置为标识键的数字代码。但是,它不确定产生了该键上的哪个字符,因此“X”和“x”具有相同的. keycode值。请参考54.5. Key names (tkdocs.com)
.keysym对于涉及特殊键的KeyPressKeyRelease事件,此属性被设置为键的字符串名称,例如,PageUp键的'Prior'。请参考54.5. Key names (tkdocs.com)
.keysym_num对于KeyPressKeyRelease事件,它被设置为.keysym字段的数字版本。对于产生单个字符的常规键,该字段被设置为键的ASCII码的整数值。特殊值请参考54.5. Key names (tkdocs.com)
.num如果事件与鼠标button相关,则该属性设置为按钮编号(1,2,3)。
.delta对于MouseWheel事件,该属性包含一个整数,其符号为正表示向上滚动,符号为负表示向下滚动。在Windows下,该值将是120的倍数;例如,120表示向上滚动一步,-240表示向下滚动两步。
.height如果事件是Configure,则将此属性设置为小部件的新高度(以像素为单位)。
.width如果事件是Configure,则将此属性设置为小部件的新宽度(以像素为单位)。
.serial一个整数序列号,每次服务器处理客户端请求时递增。可以使用.serial值来查找事件的确切时间序列:值较低的事件发生得较早。
.time该属性被设置为一个没有绝对意义的整数,但每毫秒递增一次。这允许应用程序确定,例如,两次鼠标点击之间的时间长度。
.x事件发生时鼠标的x坐标,相对于小部件的左上角。
.y事件发生时鼠标的y坐标,相对于小部件的左上角。
.x_root事件发生时鼠标相对于屏幕左上角的x坐标。
.y_root事件发生时鼠标相对于屏幕左上角的y坐标。
.state描述所有修饰符键的状态的整数。

关于 .state

MaskModifier
0X0001Shift
0X0002Caps Lock
0X0004Control
0X0008Left-hand Alt
0X0010Num Lock
0X0080Right-hand Alt
0X0100Mouse button 1
0X0200Mouse button 2
0X0400Mouse button 3

🎠弹出对话框

MessageBox消息框

消息框

一旦导入了MessageBox模块,就可以通过调用该表中的函数来创建这七种常见类型的弹出菜单中的任何一种。

showinfo(title, message, options):信息消息框

showwarning(title, message, options):警告消息框

showerror(title, message, options):错误消息框

对话框

askokcancel(title, message, options)

askquestion(title, message, options)

askretrycancel(title, message, options)

askyesno(title, message, options)

参数

在每种情况下,title都是一个字符串,将显示在窗口装饰的顶部。message参数是一个字符串,出现在弹出窗口的主体中;在这个字符串中,行以换行符('\n')分隔。

此外options

default:默认选择,如果不指定此选项,则第一个按钮(“OK”,“Yes”或“Retry”)将是默认选择。要指定哪个按钮是默认选择,使用default=C,其中CMessageBox中定义的这些常量之一:CANCEL、IGNORE、OK、NO、RETRY或YES。

icon:选择弹出窗口中出现的图标。使用icon=I形式的参数,其中IMessageBox中定义的常量之一:ERROR、INFO、QUESTION或WARNING。

parent:如果不指定此选项,弹出窗口将出现在根窗口上方。要使弹出窗口出现在子窗口W的上方,请使用参数parent=W

返回

每一个ask…弹出窗口函数返回一个值,该值取决于用户按下哪个按钮来删除弹出窗口。

  • askokcancel, askretrycancel和askyesno都返回bool值:“OK”或“Yes”选项为True“No”或“Cancel”选项为False
  • askquestion返回u' Yes'True,返回u' no'False

FileDialog文件框

窗口

askopenfilename(option=value,...):用于用户想要选择已有文件的情况,如果用户选择了一个不存在的文件,将会出现一个弹出窗口,告诉他们所选择的文件不存在。

asksaveasfilename(option=value,...):用于用户想要创建新文件或替换现有文件的情况。如果用户选择一个现有文件,将出现一个弹出窗口,告知该文件已经存在,并询问用户是否真的想要替换它。

参数

这两个函数的参数是相同的

defaultextension=s:默认的文件扩展名,以点('.')开头的字符串。如果用户的回复包含点,则此参数不起作用。在没有点的情况下,它被附加到用户的回复中。例如如果提供一个defaultextension='.jpg'参数,用户输入'test',返回的文件名将是'test.jpg'

filetypes=[(label1,pattern1), (label2,pattern2), …]:指定筛选文件类型的下拉菜单选项,该选项的值是由二元组构成的列表,每个二元组是由(类型名,后缀)构成,例如:filetypes=[('文本', '.txt'), ('图片', '.jpg'), ('动图', '.gif')]。

initialdir=D:指定打开文件的路径,默认路径是当前文件夹

initialfile=F:指定打开文件的名字。

parent=W:要使弹出窗口出现在某个窗口W上,请提供此参数。默认行为是弹出窗口将出现在应用程序的根窗口上方。

title=T:如果指定,T是一个字符串,将作为弹出窗口的标题显示。

返回

如果用户选择了一个文件,则返回值是所选文件的完整路径名。如果用户使用Cancel按钮,该函数返回一个空字符串。

ColorChooser 颜色挑选

要给应用程序的用户一个可以用来选择颜色的弹出窗口

result = ColorChooser.askcolor(color, option=value, ...)

参数

color:要显示的初始颜色。默认的初始颜色是浅灰色。

title=text:指定的文本出现在弹出窗口的标题区域。默认的标题是“Color”

parent=W:要使弹出窗口出现在某个窗口W上,请提供此参数。默认行为是弹出窗口将出现在应用程序的根窗口上方。

返回

  • 如果用户单击弹出窗口上的OK按钮,返回的值将是一个元组(triple, color),其中triple是一个元组(R, G, B),其中分别包含范围为[0,255]的红色、绿色和蓝色值,而color是作为常规Tkinter颜色对象选择的颜色。
  • 如果用户单击Cancel,该函数将返回(None, None)
    RY或YES。`

icon:选择弹出窗口中出现的图标。使用icon=I形式的参数,其中IMessageBox中定义的常量之一:ERROR、INFO、QUESTION或WARNING。

parent:如果不指定此选项,弹出窗口将出现在根窗口上方。要使弹出窗口出现在子窗口W的上方,请使用参数parent=W

返回

每一个ask…弹出窗口函数返回一个值,该值取决于用户按下哪个按钮来删除弹出窗口。

  • askokcancel, askretrycancel和askyesno都返回bool值:“OK”或“Yes”选项为True“No”或“Cancel”选项为False
  • askquestion返回u' Yes'True,返回u' no'False

FileDialog文件框

窗口

askopenfilename(option=value,...):用于用户想要选择已有文件的情况,如果用户选择了一个不存在的文件,将会出现一个弹出窗口,告诉他们所选择的文件不存在。

asksaveasfilename(option=value,...):用于用户想要创建新文件或替换现有文件的情况。如果用户选择一个现有文件,将出现一个弹出窗口,告知该文件已经存在,并询问用户是否真的想要替换它。

参数

这两个函数的参数是相同的

defaultextension=s:默认的文件扩展名,以点('.')开头的字符串。如果用户的回复包含点,则此参数不起作用。在没有点的情况下,它被附加到用户的回复中。例如如果提供一个defaultextension='.jpg'参数,用户输入'test',返回的文件名将是'test.jpg'

filetypes=[(label1,pattern1), (label2,pattern2), …]:指定筛选文件类型的下拉菜单选项,该选项的值是由二元组构成的列表,每个二元组是由(类型名,后缀)构成,例如:filetypes=[('文本', '.txt'), ('图片', '.jpg'), ('动图', '.gif')]。

initialdir=D:指定打开文件的路径,默认路径是当前文件夹

initialfile=F:指定打开文件的名字。

parent=W:要使弹出窗口出现在某个窗口W上,请提供此参数。默认行为是弹出窗口将出现在应用程序的根窗口上方。

title=T:如果指定,T是一个字符串,将作为弹出窗口的标题显示。

返回

如果用户选择了一个文件,则返回值是所选文件的完整路径名。如果用户使用Cancel按钮,该函数返回一个空字符串。

ColorChooser 颜色挑选

要给应用程序的用户一个可以用来选择颜色的弹出窗口

result = ColorChooser.askcolor(color, option=value, ...)

参数

color:要显示的初始颜色。默认的初始颜色是浅灰色。

title=text:指定的文本出现在弹出窗口的标题区域。默认的标题是“Color”

parent=W:要使弹出窗口出现在某个窗口W上,请提供此参数。默认行为是弹出窗口将出现在应用程序的根窗口上方。

返回

  • 如果用户单击弹出窗口上的OK按钮,返回的值将是一个元组(triple, color),其中triple是一个元组(R, G, B),其中分别包含范围为[0,255]的红色、绿色和蓝色值,而color是作为常规Tkinter颜色对象选择的颜色。
  • 如果用户单击Cancel,该函数将返回(None, None)
  • 22
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值