tkinter
— Tcl/Tk 的 Python 接口¶
tkinter
包(“Tk 接口”)是 Tcl/Tk GUI 工具包的标准 Python 接口。 Tk 和 tkinter
在大多数 Unix 平台(包括 macOS)以及 Windows 系统上都可用。
从命令行运行 python -m tkinter
应该会打开一个窗口,演示一个简单的 Tk 界面,让您知道 tkinter
已正确安装在您的系统上,并且还会显示已安装的 Tcl/Tk 版本,以便您可以阅读特定于该版本的 Tcl/Tk 文档。
Tkinter 支持一系列 Tcl/Tk 版本,这些版本构建时可能带有或不带有线程支持。官方 Python 二进制版本捆绑了 Tcl/Tk 8.6 线程版本。有关支持的版本的更多信息,请参阅 _tkinter
模块的源代码。
Tkinter 不是一个简单的包装器,而是添加了相当多的自身逻辑,使体验更加 Pythonic。本文档将重点介绍这些添加和更改,并参考官方 Tcl/Tk 文档以了解未更改的详细信息。
注意
Tcl/Tk 8.5 (2007) 引入了一组现代的主题用户界面组件以及用于使用它们的新 API。旧的和新的 API 仍然可用。您在网上找到的大多数文档仍然使用旧的 API,并且可能已经过时。
另请参阅
- TkDocs
关于使用 Tkinter 创建用户界面的广泛教程。解释了关键概念,并使用现代 API 说明了推荐的方法。
- Tkinter 8.5 参考:用于 Python 的 GUI
Tkinter 8.5 的参考文档,详细说明了可用的类、方法和选项。
Tcl/Tk 资源
书籍
- 面向忙碌的 Python 开发人员的现代 Tkinter
作者:Mark Roseman。(ISBN 978-1999149567)
- 使用 Tkinter 进行 Python GUI 编程
作者:Alan D. Moore。(ISBN 978-1788835886)
- Python 编程
作者:Mark Lutz;对 Tkinter 进行了出色的介绍。(ISBN 978-0596158101)
- Tcl 和 Tk 工具包(第二版)
作者:Tcl/Tk 的发明者 John Ousterhout 和 Ken Jones;不包括 Tkinter。(ISBN 978-0321336330)
架构¶
Tcl/Tk 不是一个单独的库,而是由几个不同的模块组成,每个模块都有单独的功能及其自己的官方文档。Python 的二进制发行版还附带一个附加模块。
- Tcl
Tcl 是一种动态解释型编程语言,就像 Python 一样。虽然它可以作为通用编程语言单独使用,但它最常作为脚本引擎或 Tk 工具包的接口嵌入到 C 应用程序中。Tcl 库具有 C 接口,用于创建和管理一个或多个 Tcl 解释器实例,在这些实例中运行 Tcl 命令和脚本,并添加以 Tcl 或 C 实现的自定义命令。每个解释器都有一个事件队列,并且有工具可以向其发送事件并处理它们。与 Python 不同,Tcl 的执行模型围绕协作式多任务处理而设计,而 Tkinter 弥合了这种差异(有关详细信息,请参阅 线程模型)。
- Tk
Tk 是一个以 C 实现的 Tcl 包,它添加了自定义命令来创建和操作 GUI 小部件。每个
Tk
对象都嵌入了自己的 Tcl 解释器实例,并在其中加载了 Tk。Tk 的小部件非常可自定义,但代价是外观过时。Tk 使用 Tcl 的事件队列来生成和处理 GUI 事件。- Ttk
主题 Tk (Ttk) 是较新的 Tk 小部件系列,与许多经典 Tk 小部件相比,它在不同平台上提供了更好的外观。Ttk 作为 Tk 的一部分分发,从 Tk 版本 8.5 开始。Python 绑定在单独的模块
tkinter.ttk
中提供。
在内部,Tk 和 Ttk 使用底层操作系统的工具,即 Unix/X11 上的 Xlib、macOS 上的 Cocoa、Windows 上的 GDI。
当您的 Python 应用程序使用 Tkinter 中的类(例如,创建小部件)时,tkinter
模块首先组装一个 Tcl/Tk 命令字符串。它将 Tcl 命令字符串传递给内部的 _tkinter
二进制模块,然后该模块调用 Tcl 解释器对其进行求值。然后,Tcl 解释器将调用 Tk 和/或 Ttk 包,而 Tk 和/或 Ttk 包又将调用 Xlib、Cocoa 或 GDI。
Tkinter 模块¶
对 Tkinter 的支持分布在多个模块中。大多数应用程序将需要主 tkinter
模块以及 tkinter.ttk
模块,该模块提供了现代的主题小部件集和 API
from tkinter import *
from tkinter import ttk
- class tkinter.Tk(screenName=None, baseName=None, className='Tk', useTk=True, sync=False, use=None)¶
构造一个顶层 Tk 小部件,它通常是应用程序的主窗口,并为此小部件初始化一个 Tcl 解释器。每个实例都有自己关联的 Tcl 解释器。
Tk
类通常使用所有默认值进行实例化。但是,当前识别以下关键字参数- screenName
当给定(作为字符串)时,设置
DISPLAY
环境变量。(仅限 X11)- baseName
配置文件名。默认情况下,baseName 派生自程序名称 (
sys.argv[0]
)。- className
小部件类的名称。用作配置文件,也用作调用 Tcl 的名称 (interp 中的 argv0)。
- useTk
如果为
True
,则初始化 Tk 子系统。tkinter.Tcl()
函数将其设置为False
。- sync
如果为
True
,则同步执行所有 X 服务器命令,以便立即报告错误。可用于调试。(仅限 X11)- use
指定要嵌入应用程序的窗口的 id,而不是将其创建为独立的顶层窗口。id 必须以与顶层小部件的 -use 选项值相同的方式指定(也就是说,它的形式类似于
winfo_id()
返回的形式)。请注意,在某些平台上,只有当 id 引用启用了 -container 选项的 Tk 框架或顶层时,此操作才能正常工作。
Tk
将配置文件(命名为.className.tcl
和.baseName.tcl
)读取并解释到 Tcl 解释器中,并在.className.py
和.baseName.py
的内容上调用exec()
。配置文件路径是HOME
环境变量,如果未定义,则为os.curdir
。
- tkinter.Tcl(screenName=None, baseName=None, className='Tk', useTk=False)¶
Tcl()
函数是一个工厂函数,它创建的对象与Tk
类创建的对象非常相似,只是它不初始化 Tk 子系统。这在以下情况下最有用:在不需要创建额外顶层窗口的环境中驱动 Tcl 解释器,或者在无法创建顶层窗口的环境中(例如没有 X 服务器的 Unix/Linux 系统)。 通过调用其loadtk()
方法,Tcl()
对象创建的对象可以创建一个顶层窗口(并初始化 Tk 子系统)。
提供 Tk 支持的模块包括
tkinter
主 Tkinter 模块。
tkinter.colorchooser
用于让用户选择颜色的对话框。
tkinter.commondialog
此处列出的其他模块中定义的对话框的基类。
tkinter.filedialog
用于让用户指定要打开或保存的文件的常用对话框。
tkinter.font
帮助处理字体的实用工具。
tkinter.messagebox
访问标准 Tk 对话框。
tkinter.scrolledtext
内置垂直滚动条的文本小部件。
tkinter.simpledialog
基本对话框和便捷函数。
tkinter.ttk
Tk 8.5 中引入的主题小部件集,为
tkinter
主模块中的许多经典小部件提供了现代替代方案。
其他模块
_tkinter
包含 Tcl/Tk 底层接口的二进制模块。它由
tkinter
主模块自动导入,应用程序员永远不应直接使用它。它通常是一个共享库(或 DLL),但在某些情况下可能会与 Python 解释器静态链接。idlelib
Python 的集成开发和学习环境 (IDLE)。基于
tkinter
。tkinter.constants
在将各种参数传递给 Tkinter 调用时,可以用来代替字符串的符号常量。由
tkinter
主模块自动导入。tkinter.dnd
(实验性)为
tkinter
提供拖放支持。当它被 Tk DND 替换时,将被弃用。turtle
Tk 窗口中的 Turtle 图形。
Tkinter 救生指南¶
本节并非旨在对 Tk 或 Tkinter 进行详尽的教程。为此,请参阅前面提到的外部资源之一。相反,本节提供了一个关于 Tkinter 应用程序外观的快速入门,确定了基本的 Tk 概念,并解释了 Tkinter 包装器的结构。
本节的其余部分将帮助您识别 Tkinter 应用程序中需要的类、方法和选项,以及在哪里找到关于它们的更详细文档,包括在官方 Tcl/Tk 参考手册中。
一个 Hello World 程序¶
我们将从在 Tkinter 中逐步完成一个“Hello World”应用程序开始。这不是我们能编写的最小的一个,但它足以说明您需要了解的一些关键概念。
from tkinter import *
from tkinter import ttk
root = Tk()
frm = ttk.Frame(root, padding=10)
frm.grid()
ttk.Label(frm, text="Hello World!").grid(column=0, row=0)
ttk.Button(frm, text="Quit", command=root.destroy).grid(column=1, row=0)
root.mainloop()
导入后,下一行创建 Tk
类的实例,该实例初始化 Tk 并创建其关联的 Tcl 解释器。它还创建一个顶层窗口,称为根窗口,它充当应用程序的主窗口。
下一行创建一个框架小部件,在本例中,它将包含一个标签和一个我们将接下来创建的按钮。该框架适合在根窗口内。
下一行创建一个标签小部件,其中包含静态文本字符串。grid()
方法用于指定标签在其包含框架小部件内的相对布局(位置),类似于 HTML 中表格的工作方式。
然后创建一个按钮小部件,并将其放置在标签的右侧。按下时,它将调用根窗口的 destroy()
方法。
最后,mainloop()
方法将所有内容放在显示屏上,并响应用户输入,直到程序终止。
重要的 Tk 概念¶
即使是这个简单的程序也说明了以下关键 Tk 概念
- 小部件
Tkinter 用户界面由各个小部件组成。每个小部件都表示为一个 Python 对象,从诸如
ttk.Frame
、ttk.Label
和ttk.Button
等类实例化。- 小部件层次结构
小部件以层次结构排列。标签和按钮包含在框架内,而框架又包含在根窗口内。在创建每个子小部件时,其父小部件作为第一个参数传递给小部件构造函数。
- 配置选项
小部件具有配置选项,可修改其外观和行为,例如在标签或按钮中显示的文本。不同的小部件类将具有不同的选项集。
- 几何管理
小部件在创建时不会自动添加到用户界面中。像
grid
这样的几何管理器控制它们在用户界面中的放置位置。- 事件循环
Tkinter 仅在主动运行事件循环时才会对用户输入、程序中的更改甚至刷新显示做出反应。如果您的程序没有运行事件循环,则用户界面将不会更新。
了解 Tkinter 如何包装 Tcl/Tk¶
当您的应用程序使用 Tkinter 的类和方法时,Tkinter 内部正在组装表示 Tcl/Tk 命令的字符串,并在附加到应用程序 Tk
实例的 Tcl 解释器中执行这些命令。
无论是尝试浏览参考文档、尝试查找正确的方法或选项、改编一些现有代码还是调试您的 Tkinter 应用程序,有时了解这些底层 Tcl/Tk 命令的样子会很有用。
为了说明,下面是上述 Tkinter 脚本主要部分的 Tcl/Tk 等效项。
ttk::frame .frm -padding 10
grid .frm
grid [ttk::label .frm.lbl -text "Hello World!"] -column 0 -row 0
grid [ttk::button .frm.btn -text "Quit" -command "destroy ."] -column 1 -row 0
Tcl 的语法类似于许多 shell 语言,其中第一个单词是要执行的命令,后面跟着该命令的参数,并用空格分隔。 在不涉及太多细节的情况下,请注意以下事项
用于创建小部件的命令(如
ttk::frame
)对应于 Tkinter 中的小部件类。Tcl 部件选项(如
-text
)对应于 Tkinter 中的关键字参数。在 Tcl 中,部件通过路径名引用(如
.frm.btn
),而 Tkinter 不使用名称,而是使用对象引用。部件在部件层次结构中的位置编码在其(分层)路径名中,该路径名使用
.
(点)作为路径分隔符。根窗口的路径名只是.
(点)。在 Tkinter 中,层次结构不是通过路径名定义的,而是在创建每个子部件时指定父部件来定义的。在 Tcl 中作为单独命令实现的运算(如
grid
或destroy
)在 Tkinter 部件对象上表示为方法。您很快就会看到,在其他时候,Tcl 使用的似乎是部件对象上的方法调用,这更接近于 Tkinter 中使用的内容。
我该如何……?什么选项会……?¶
如果您不确定如何在 Tkinter 中执行某项操作,并且您无法在使用的教程或参考文档中立即找到它,那么有一些策略可能会有所帮助。
首先,请记住,各个部件的工作方式的详细信息可能会因 Tkinter 和 Tcl/Tk 的不同版本而异。如果您正在搜索文档,请确保它与系统上安装的 Python 和 Tcl/Tk 版本相对应。
在搜索如何使用 API 时,了解您正在使用的类、选项或方法的准确名称很有帮助。内省,无论是在交互式 Python shell 中还是使用 print()
,都可以帮助您识别所需的内容。
要了解任何部件上可用的配置选项,请调用其 configure()
方法,该方法返回一个字典,其中包含有关每个对象的各种信息,包括其默认值和当前值。使用 keys()
仅获取每个选项的名称。
btn = ttk.Button(frm, ...)
print(btn.configure().keys())
由于大多数部件都有许多共同的配置选项,因此找出特定于特定部件类的选项可能很有用。将选项列表与更简单的部件(如框架)的选项列表进行比较是一种方法。
print(set(btn.configure().keys()) - set(frm.configure().keys()))
同样,您可以使用标准 dir()
函数找到部件对象的可用方法。如果您尝试一下,您会看到有 200 多个常用部件方法,因此再次识别特定于部件类的方法是有帮助的。
print(dir(btn))
print(set(dir(btn)) - set(dir(frm)))
线程模型¶
Python 和 Tcl/Tk 具有非常不同的线程模型,tkinter
试图弥合这些模型之间的差距。如果您使用线程,您可能需要注意这一点。
一个 Python 解释器可能关联有多个线程。在 Tcl 中,可以创建多个线程,但每个线程都有一个单独的 Tcl 解释器实例与之关联。线程还可以创建多个解释器实例,尽管每个解释器实例只能由创建它的一个线程使用。
tkinter
创建的每个 Tk
对象都包含一个 Tcl 解释器。它还会跟踪哪个线程创建了该解释器。可以从任何 Python 线程调用 tkinter
。在内部,如果调用来自创建 Tk
对象的线程之外的线程,则会将一个事件发布到解释器的事件队列,并且在执行时,结果将返回给调用 Python 线程。
Tcl/Tk 应用程序通常是事件驱动的,这意味着在初始化之后,解释器会运行一个事件循环(即 Tk.mainloop()
)并响应事件。由于它是单线程的,因此事件处理程序必须快速响应,否则它们将阻止处理其他事件。为了避免这种情况,任何长时间运行的计算都不应在事件处理程序中运行,而是使用计时器分解为更小的部分,或者在另一个线程中运行。这与许多 GUI 工具包不同,在这些工具包中,GUI 在一个与所有应用程序代码(包括事件处理程序)完全不同的线程中运行。
如果 Tcl 解释器没有运行事件循环和处理事件,则从运行 Tcl 解释器的线程之外的线程进行的任何 tkinter
调用都将失败。
存在一些特殊情况
可以构建 Tcl/Tk 库,使其不感知线程。在这种情况下,
tkinter
会从原始 Python 线程调用库,即使这与创建 Tcl 解释器的线程不同。全局锁可确保一次只发生一个调用。虽然
tkinter
允许您创建Tk
对象(及其自己的解释器)的多个实例,但是属于同一线程的所有解释器共享一个公共事件队列,这会很快变得混乱。实际上,一次不要创建多个Tk
实例。否则,最好在单独的线程中创建它们,并确保您正在运行感知线程的 Tcl/Tk 构建。阻塞事件处理程序并不是阻止 Tcl 解释器重新进入事件循环的唯一方法。甚至可以运行多个嵌套的事件循环或完全放弃事件循环。如果您在事件或线程方面做任何棘手的事情,请注意这些可能性。
有一些选定的
tkinter
函数目前仅在从创建 Tcl 解释器的线程调用时才起作用。
方便参考¶
设置选项¶
选项控制着部件的颜色和边框宽度等内容。可以通过三种方式设置选项
- 在对象创建时,使用关键字参数
fred = Button(self, fg="red", bg="blue")
- 在对象创建后,将选项名称视为字典索引
fred["fg"] = "red" fred["bg"] = "blue"
- 使用 config() 方法更新对象创建后的多个属性
fred.config(fg="red", bg="blue")
有关给定选项及其行为的完整说明,请参阅有关部件的 Tk 手册页。
请注意,手册页列出了每个部件的“标准选项”和“部件特定选项”。前者是许多部件共有的选项列表,后者是特定于该部件的选项。标准选项记录在 options(3) 手册页上。
本文档中不区分标准选项和小部件特定选项。某些选项不适用于某些类型的小部件。给定的小部件是否响应特定选项取决于小部件的类;按钮具有 command
选项,而标签没有。
给定小部件支持的选项列在该小部件的手册页中,或者可以通过调用不带参数的 config()
方法在运行时查询,或者通过调用该小部件的 keys()
方法进行查询。这些调用的返回值是一个字典,其键是选项名称的字符串(例如,'relief'
),其值是 5 元组。
某些选项,如 bg
是长名称的常见选项的同义词(bg
是“background”的缩写)。将速记选项的名称传递给 config()
方法将返回一个 2 元组,而不是 5 元组。返回的 2 元组将包含同义词的名称和“真实”选项(例如 ('bg', 'background')
)。
索引 |
含义 |
示例 |
---|---|---|
0 |
选项名称 |
|
1 |
用于数据库查找的选项名称 |
|
2 |
用于数据库查找的选项类 |
|
3 |
默认值 |
|
4 |
当前值 |
|
示例
>>> print(fred.config())
{'relief': ('relief', 'relief', 'Relief', 'raised', 'groove')}
当然,打印的字典将包含所有可用的选项及其值。这只是一个示例。
打包器¶
打包器是 Tk 的几何管理机制之一。几何管理器用于指定小部件在其容器(它们的相互主控)中的相对位置。与更麻烦的放置器(较少使用,我们在此处不介绍)相比,打包器接受定性关系规范(上方、左侧、填充等),并计算出精确的放置坐标。
任何主控小部件的大小都由内部的“从属小部件”的大小决定。打包器用于控制从属小部件在其打包到的主控内部的显示位置。您可以将小部件打包到框架中,并将框架打包到其他框架中,以实现您想要的布局。此外,一旦打包,布局会动态调整以适应配置的增量更改。
请注意,在通过几何管理器指定其几何之前,小部件不会出现。一个常见的早期错误是遗漏几何规范,然后当小部件创建但什么也没出现时感到惊讶。只有在例如,对其应用了打包器的 pack()
方法之后,小部件才会出现。
可以使用控制小部件在其容器中显示位置以及主应用程序窗口调整大小时其行为方式的关键字-选项/值对调用 pack() 方法。以下是一些示例
fred.pack() # defaults to side = "top"
fred.pack(side="left")
fred.pack(expand=1)
打包器选项¶
有关打包器及其可以采用的选项的更详细信息,请参阅手册页和 John Ousterhout 的书的第 183 页。
- anchor
锚点类型。表示打包器在每个从属部件的包裹中放置它的位置。
- expand
布尔值,
0
或1
。- fill
合法值:
'x'
、'y'
、'both'
、'none'
。- ipadx 和 ipady
距离 - 表示从属小部件每侧的内部填充。
- padx 和 pady
距离 - 表示从属小部件每侧的外部填充。
- side
合法值是:
'left'
、'right'
、'top'
、'bottom'
。
耦合小部件变量¶
某些小部件(如文本输入小部件)的当前值设置可以通过使用特殊选项直接连接到应用程序变量。这些选项是 variable
、textvariable
、onvalue
、offvalue
和 value
。此连接是双向的:如果变量由于任何原因发生更改,则与其连接的小部件将更新以反映新值。
不幸的是,在 tkinter
的当前实现中,不可能通过 variable
或 textvariable
选项将任意 Python 变量传递给小部件。唯一可行的变量类型是从 tkinter
中定义的名为 Variable 的类继承而来的变量。
已经定义了许多有用的 Variable 子类:StringVar
、IntVar
、DoubleVar
和 BooleanVar
。要读取此类变量的当前值,请调用其上的 get()
方法,要更改其值,请调用 set()
方法。如果您遵循此协议,小部件将始终跟踪变量的值,无需您进一步干预。
例如
import tkinter as tk
class App(tk.Frame):
def __init__(self, master):
super().__init__(master)
self.pack()
self.entrythingy = tk.Entry()
self.entrythingy.pack()
# Create the application variable.
self.contents = tk.StringVar()
# Set it to some value.
self.contents.set("this is a variable")
# Tell the entry widget to watch this variable.
self.entrythingy["textvariable"] = self.contents
# Define a callback for when the user hits return.
# It prints the current value of the variable.
self.entrythingy.bind('<Key-Return>',
self.print_contents)
def print_contents(self, event):
print("Hi. The current entry content is:",
self.contents.get())
root = tk.Tk()
myapp = App(root)
myapp.mainloop()
窗口管理器¶
在 Tk 中,有一个实用程序命令 wm
,用于与窗口管理器交互。wm
命令的选项允许您控制诸如标题、放置、图标位图等内容。在 tkinter
中,这些命令已作为 Wm
类的方法实现。顶级小部件是从 Wm
类继承的,因此可以直接调用 Wm
方法。
要访问包含给定小部件的顶级窗口,您通常可以直接引用该小部件的主控。当然,如果小部件已被打包在框架内,则主控将不代表顶级窗口。要访问包含任意小部件的顶级窗口,您可以调用 _root()
方法。此方法以一个下划线开头,表示该函数是实现的一部分,而不是 Tk 功能的接口。
以下是一些典型用法的示例
import tkinter as tk
class App(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.pack()
# create the application
myapp = App()
#
# here are method calls to the window manager class
#
myapp.master.title("My Do-Nothing Application")
myapp.master.maxsize(1000, 400)
# start the program
myapp.mainloop()
Tk 选项数据类型¶
- anchor
合法值是指南针的点:
"n"
、"ne"
、"e"
、"se"
、"s"
、"sw"
、"w"
、"nw"
,以及"center"
。- bitmap
有八个内置的命名位图:
'error'
、'gray25'
、'gray50'
、'hourglass'
、'info'
、'questhead'
、'question'
、'warning'
。要指定 X 位图文件名,请提供该文件的完整路径,并在前面加上@
,如"@/usr/contrib/bitmap/gumby.bit"
。- boolean
您可以传递整数 0 或 1 或字符串
"yes"
或"no"
。- callback
这是任何不带参数的 Python 函数。例如
def print_it(): print("hi there") fred["command"] = print_it
- color
颜色可以作为 rgb.txt 文件中 X 颜色的名称给出,也可以作为表示 4 位 RGB 值的字符串给出:
"#RGB"
、8 位:"#RRGGBB"
、12 位:"#RRRGGGBBB"
或 16 位:"#RRRRGGGGBBBB"
范围,其中 R、G、B 此处表示任何合法的十六进制数字。有关详细信息,请参见 Ousterhout 的书第 160 页。- cursor
可以使用
cursorfont.h
中的标准 X 光标名称,而无需XC_
前缀。例如,要获得手形光标 (XC_hand2
),请使用字符串"hand2"
。您还可以指定自己的位图和掩码文件。请参见 Ousterhout 的书第 179 页。- distance
屏幕距离可以指定为像素或绝对距离。像素以数字形式给出,绝对距离以字符串形式给出,尾随字符表示单位:
c
表示厘米,i
表示英寸,m
表示毫米,p
表示打印机点。例如,3.5 英寸表示为"3.5i"
。- font
Tk 使用列表字体名称格式,例如
{courier 10 bold}
。字体大小的正数以点为单位度量;负数的大小以像素为单位度量。- geometry
这是一个
宽度x高度
形式的字符串,其中宽度和高度以像素为单位测量大多数小部件(对于显示文本的小部件,以字符为单位)。例如:fred["geometry"] = "200x100"
。- justify
合法值是字符串:
"left"
、"center"
、"right"
和"fill"
。- region
这是一个包含四个空格分隔元素的字符串,每个元素都是合法的距离值(见上文)。例如:
"2 3 4 5"
和"3i 2i 4.5i 2i"
以及"3c 2c 4c 10.43c"
都是合法的区域。- relief
确定小部件的边框样式。合法的值包括:
"raised"
、"sunken"
、"flat"
、"groove"
和"ridge"
。- scrollcommand
这几乎总是某个滚动条小部件的
set()
方法,但也可以是任何接受单个参数的小部件方法。- wrap
必须是以下之一:
"none"
、"char"
或"word"
。
绑定和事件¶
小部件命令的 bind 方法允许你监视特定事件,并在该事件类型发生时触发回调函数。bind 方法的形式如下:
def bind(self, sequence, func, add=''):
其中
- sequence
是一个字符串,表示目标事件的类型。(有关详细信息,请参阅 bind(3tk) 手册页和 John Ousterhout 的著作《Tcl and the Tk Toolkit (第二版)》第 201 页)。
- func
是一个 Python 函数,接受一个参数,当事件发生时将被调用。一个 Event 实例将作为参数传递。(以这种方式部署的函数通常被称为回调。)
- add
是可选的,可以是
''
或'+'
。传递空字符串表示此绑定将替换与此事件关联的任何其他绑定。传递'+'
表示此函数将添加到绑定到此事件类型的函数列表中。
例如
def turn_red(self, event):
event.widget["activeforeground"] = "red"
self.button.bind("<Enter>", self.turn_red)
请注意在 turn_red()
回调中如何访问事件的 widget 字段。此字段包含捕获 X 事件的小部件。下表列出了您可以访问的其他事件字段,以及它们在 Tk 中的表示方式,这在参考 Tk 手册页时可能很有用。
Tk |
Tkinter 事件字段 |
Tk |
Tkinter 事件字段 |
---|---|---|---|
%f |
focus |
%A |
char |
%h |
height |
%E |
send_event |
%k |
keycode |
%K |
keysym |
%s |
state |
%N |
keysym_num |
%t |
time |
%T |
type |
%w |
width |
%W |
widget |
%x |
x |
%X |
x_root |
%y |
y |
%Y |
y_root |
索引参数¶
许多小部件需要传递“索引”参数。这些参数用于指向 Text 小部件中的特定位置,或指向 Entry 小部件中的特定字符,或指向 Menu 小部件中的特定菜单项。
- Entry 小部件索引(index、view index 等)
Entry 小部件具有引用正在显示的文本中的字符位置的选项。您可以使用这些
tkinter
函数来访问文本小部件中的这些特殊点- Text 小部件索引
Text 小部件的索引表示法非常丰富,最好在 Tk 手册页中描述。
- 菜单索引(menu.invoke()、menu.entryconfig() 等)
菜单的一些选项和方法会操作特定的菜单项。当选项或参数需要菜单索引时,你可以传入:
一个整数,它指的是菜单项在小部件中的数字位置,从顶部开始计数,从 0 开始;
字符串
"active"
,它指的是当前在光标下的菜单位置;字符串
"last"
,它指的是最后一个菜单项;以
@
开头的整数,例如@6
,其中整数被解释为菜单坐标系中的 y 像素坐标;字符串
"none"
,表示根本没有菜单项,最常与 menu.activate() 一起使用以停用所有条目,最后,一个文本字符串,该字符串与菜单项的标签进行模式匹配,从菜单的顶部到底部扫描。请注意,此索引类型在所有其他类型之后考虑,这意味着标签为
last
、active
或none
的菜单项的匹配可能会被解释为上述文字。
图像¶
可以通过 tkinter.Image
的相应子类创建不同格式的图像
BitmapImage
用于 XBM 格式的图像。PhotoImage
用于 PGM、PPM、GIF 和 PNG 格式的图像。后者从 Tk 8.6 开始支持。
这两种类型的图像都是通过 file
或 data
选项创建的(其他选项也可用)。
在 3.13 版本中更改: 添加了 PhotoImage
方法 copy_replace()
,用于将一个图像中的区域复制到另一个图像,可以进行像素缩放和/或子采样。将 from_coords 参数添加到 PhotoImage
方法 copy()
、zoom()
和 subsample()
。将 zoom 和 subsample 参数添加到 PhotoImage
方法 copy()
。
然后,可以在某些小部件(例如,标签、按钮、菜单)支持 image
选项的任何地方使用图像对象。在这些情况下,Tk 不会保留对图像的引用。当删除对图像对象的最后一个 Python 引用时,图像数据也会被删除,Tk 将在使用了图像的任何地方显示一个空框。
另请参阅
Pillow 包添加了对 BMP、JPEG、TIFF 和 WebP 等格式的支持。
文件处理器¶
Tk 允许你注册和注销一个回调函数,当文件描述符上可以进行 I/O 操作时,该回调函数将从 Tk 主循环中调用。每个文件描述符只能注册一个处理程序。示例代码
import tkinter
widget = tkinter.Tk()
mask = tkinter.READABLE | tkinter.WRITABLE
widget.tk.createfilehandler(file, mask, callback)
...
widget.tk.deletefilehandler(file)
此功能在 Windows 上不可用。
由于你不知道有多少字节可用于读取,因此你可能不想使用 BufferedIOBase
或 TextIOBase
read()
或 readline()
方法,因为这些方法会坚持读取预定义数量的字节。对于套接字,recv()
或 recvfrom()
方法可以正常工作;对于其他文件,请使用原始读取或 os.read(file.fileno(), maxbytecount)
。
- Widget.tk.createfilehandler(file, mask, func)¶
注册文件处理程序回调函数 func。file 参数可以是具有
fileno()
方法的对象(例如文件或套接字对象),或一个整数文件描述符。mask 参数是以下三个常数的 OR 组合。回调按以下方式调用callback(file, mask)
- Widget.tk.deletefilehandler(file)¶
注销文件处理程序。