tkinter — Tcl/Tk 的 Python 接口 — Python 文档

来自菜鸟教程
Python/docs/3.9/library/tkinter
跳转至:导航、​搜索

tkinter — Tcl/Tk 的 Python 接口

源代码: :source:`Lib/tkinter/__init__.py`



tkinter 包(“Tk 接口”)是 Tcl/Tk GUI 工具包的标准 Python 接口。 Tk 和 tkinter 在大多数 Unix 平台(包括 macOS)以及 Windows 系统上都可用。

从命令行运行 python -m tkinter 应该会打开一个窗口,演示一个简单的 Tk 界面,让您知道 tkinter 已正确安装在您的系统上,并显示安装了哪个版本的 Tcl/Tk ,因此您可以阅读特定于该版本的 Tcl/Tk 文档。

也可以看看

  • *; 文档
    关于使用 Tkinter 创建用户界面的广泛教程。 解释关键概念,并说明使用现代 API 的推荐方法。
  • *; Tkinter 8.5 参考:Python 的 GUI
    Tkinter 8.5 的参考文档详细说明了可用的类、方法和选项。

Tcl/Tk 资源:

  • *; Tk 命令
    对 Tkinter 使用的每个底层 Tcl/Tk 命令的综合参考。
  • *; Tcl/Tk 主页
    附加文档以及指向 Tcl/Tk 核心开发的链接。

图书:


Tkinter 模块

对 Tkinter 的支持分布在多个模块中。 大多数应用程序将需要主 tkinter 模块,以及 tkinter.ttk 模块,该模块提供现代主题小部件集和 API:

from tkinter import *
from tkinter import ttk
class tkinter.Tk(screenName=None, baseName=None, className='Tk', useTk=1)
Tk 类是在没有参数的情况下实例化的。 这将创建 Tk 的顶级小部件,它通常是应用程序的主窗口。 每个实例都有自己关联的 Tcl 解释器。
tkinter.Tcl(screenName=None, baseName=None, className='Tk', useTk=0)
Tcl() 函数是一个工厂函数,它创建的对象与 Tk 类创建的对象非常相似,只是它不初始化 Tk 子系统。 在不想创建无关的顶层窗口或不能创建的环境(例如没有 X 服务器的 Unix/Linux 系统)中驱动 Tcl 解释器时,这通常很有用。 由 Tcl() 对象创建的对象可以通过调用其 loadtk() 方法来创建顶层窗口(并初始化 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 取代时,它将被弃用。
tkinter.tix
(不推荐使用)一个旧的第三方 Tcl/Tk 包,它添加了几个新的小部件。 在 tkinter.ttk 中可以找到大多数更好的替代方案。
turtle
Tk 窗口中的海龟图形。


Tkinter 生命保护器

本节并非设计为关于 Tk 或 Tkinter 的详尽教程。 相反,它旨在作为一个停止间隙,为系统提供一些介绍性的方向。

学分:

  • Tk 是由 John Ousterhout 在伯克利写的。
  • Tkinter 由 Steen Lumholt 和 Guido van Rossum 编写。
  • 这个 Life Preserver 是由弗吉尼亚大学的 Matt Conway 编写的。
  • HTML 渲染和一些自由编辑是由 Ken Manheimer 从 FrameMaker 版本生成的。
  • Fredrik Lundh 详细阐述并修改了类接口描述,以使它们与 Tk 4.2 保持同步。
  • Mike Clarkson 将文档转换为 LaTeX,并编译了参考手册的用户界面章节。

如何使用本节

本节设计为两部分:前半部分(大致)涵盖背景材料,而后半部分可以作为键盘参考。

当试图回答“我如何做 blah”形式的问题时,通常最好找出如何在直接 Tk 中做“blah”,然后将其转换回相应的 tkinter 调用。 Python 程序员通常可以通过查看 Tk 文档来猜测正确的 Python 命令。 这意味着为了使用 Tkinter,您必须对 Tk 有所了解。 本文档无法履行该角色,因此我们所能做的最好的事情就是向您指出现有的最佳文档。 这里有一些提示:

  • 作者强烈建议获取 Tk 手册页的副本。 具体来说,manN 目录中的手册页最有用。 man3 手册页描述了 Tk 库的 C 接口,因此对脚本编写者不是特别有用。
  • Addison-Wesley 出版了一本名为 Tcl and the Tk Toolkit 的书,由 John Ousterhout (ISBN 0-201-63337-X) 编写,这是对新手来说很好的 Tcl 和 Tk 介绍。 本书并非详尽无遗,许多细节参见手册页。
  • tkinter/__init__.py 对大多数人来说是最后的手段,但当其他一切都没有意义时,它可能是一个不错的去处。


一个简单的 Hello World 程序

import tkinter as tk

class Application(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.master = master
        self.pack()
        self.create_widgets()

    def create_widgets(self):
        self.hi_there = tk.Button(self)
        self.hi_there["text"] = "Hello World\n(click me)"
        self.hi_there["command"] = self.say_hi
        self.hi_there.pack(side="top")

        self.quit = tk.Button(self, text="QUIT", fg="red",
                              command=self.master.destroy)
        self.quit.pack(side="bottom")

    def say_hi(self):
        print("hi there, everyone!")

root = tk.Tk()
app = Application(master=root)
app.mainloop()

对 Tcl/Tk 的(非常)快速浏览

类层次结构看起来很复杂,但在实际操作中,应用程序程序员几乎总是引用层次结构最底层的类。

笔记:

  • 提供这些类是为了在一个命名空间下组织某些功能。 它们并不意味着独立实例化。
  • Tk 类旨在在应用程序中仅实例化一次。 应用程序程序员不需要显式实例化一个,只要实例化任何其他类,系统就会创建一个。
  • Widget 类不打算被实例化,它只用于子类化以制作“真正的”小部件(在 C++ 中,这称为“抽象类”)。

为了使用此参考资料,有时您需要知道如何阅读 Tk 的短文以及如何识别 Tk 命令的各个部分。 (请参阅 将基本 Tk 映射到 Tkinter 部分,了解 tkinter 与以下内容的等效内容。)

Tk 脚本是 Tcl 程序。 与所有 Tcl 程序一样,Tk 脚本只是由空格分隔的标记列表。 Tk 小部件只是它的 class、帮助配置它的 options 和使它做有用事情的 actions

要在 Tk 中制作小部件,命令始终采用以下形式:

classCommand newPathname options
类命令
表示要制作哪种小部件(按钮、标签、菜单……)
新路径名
是此小部件的新名称。 Tk 中的所有名称都必须是唯一的。 为了帮助加强这一点,Tk 中的小部件以 路径名 命名,就像文件系统中的文件一样。 顶级小部件 root 称为 .(句点),子元素由更多句点分隔。 例如,.myApp.controlPanel.okButton 可能是小部件的名称。
选项
配置小部件的外观以及在某些情况下的行为。 选项以标志和值列表的形式出现。 标志前面有一个“-”,就像 Unix shell 命令标志一样,如果值超过一个单词,则将它们放在引号中。

例如:

button   .fred   -fg red -text "hi there"
   ^       ^     \______________________/
   |       |                |
 class    new            options
command  widget  (-opt val -opt val ...)

创建后,小部件的路径名成为一个新命令。 这个新的 小部件命令 是程序员的句柄,用于让新小部件执行某些 操作 。 在 C 中,您可以将其表示为 someAction(fred, someOptions),在 C++ 中,您可以将其表示为 fred.someAction(someOptions),而在 Tk 中,您可以说:

.fred someAction someOptions

请注意,对象名称 .fred 以点开头。

如您所料,someAction 的合法值将取决于小部件的类:.fred disable 如果 fred 是按钮(fred 变灰)有效,但如果 fred 无效则无效标签(Tk 不支持禁用标签)。

someOptions 的合法值取决于动作。 某些操作,例如 disable,不需要参数,而其他操作,例如文本输入框的 delete 命令,需要参数来指定要删除的文本范围。


将基本 Tk 映射到 Tkinter

Tk 中的类命令对应于 Tkinter 中的类构造函数。

button .fred                =====>  fred = Button()

对象的主人隐含在创建时赋予它的新名称中。 在 Tkinter 中,明确指定了主人。

button .panel.fred          =====>  fred = Button(panel)

Tk 中的配置选项在带连字符的标签列表中给出,后跟值。 在 Tkinter 中,选项被指定为实例构造函数中的关键字参数,关键字参数用于配置调用或作为实例索引,以字典样式,用于已建立的实例。 有关设置选项,请参阅 设置选项 部分。

button .fred -fg red        =====>  fred = Button(panel, fg="red")
.fred configure -fg red     =====>  fred["fg"] = red
                            OR ==>  fred.config(fg="red")

在 Tk 中,要对小部件执行操作,请将小部件名称用作命令,并在其后跟一个动作名称,可能还带有参数(选项)。 在 Tkinter 中,您可以调用类实例上的方法来调用小部件上的操作。 tkinter/__init__.py 中列出了给定小部件可以执行的操作(方法)。

.fred invoke                =====>  fred.invoke()

要将小部件提供给打包程序(几何管理器),您可以使用可选参数调用 pack。 在 Tkinter 中,Pack 类拥有所有这些功能,并且各种形式的 pack 命令都被实现为方法。 tkinter 中的所有小部件都是从 Packer 继承的子类,因此继承了所有的打包方法。 有关表单几何管理器的其他信息,请参阅 tkinter.tix 模块文档。

pack .fred -side left       =====>  fred.pack(side="left")

方便参考

设置选项

选项控制小部件的颜色和边框宽度等内容。 可以通过三种方式设置选项:

在对象创建时,使用关键字参数
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 是“背景”的简写)。 将 config() 方法传递给速记选项的名称将返回一个 2 元组,而不是 5 元组。 传回的 2 元组将包含同义词的名称和“真实”选项(例如 ('bg', 'background'))。

指数 意义 例子
0 选项名称 'relief'
1 数据库查找的选项名称 'relief'
2 用于数据库查找的选项类 'Relief'
3 默认值 'raised'
4 当前值 'groove'

例子:

>>> print(fred.config())
{'relief': ('relief', 'relief', 'Relief', 'raised', 'groove')}

当然,打印的字典将包括所有可用选项及其值。 这仅作为示例。


包装工

封隔器是 Tk 的几何管理机制之一。 几何管理器用于指定小部件在其容器内的相对定位 - 它们的相互 master。 相对于比较笨重的placer(使用较少,这里不做介绍),packer采取定性关系规范——aboveto the left of填充 等 - 并努力为您确定确切的放置坐标。

任何 master 小部件的大小由内部“从属小部件”的大小决定。 打包器用于控制从属部件在它们被打包到的主部件中出现的位置。 您可以将小部件打包到框架中,并将框架打包到其他框架中,以实现您想要的那种布局。 此外,一旦打包,该安排会动态调整以适应配置的增量更改。

请注意,在使用几何管理器指定几何之前,小部件不会出现。 忽略几何规范是一个常见的早期错误,然后当小部件被创建但什么也没出现时会感到惊讶。 小部件只有在它应用了例如打包程序的 pack() 方法后才会出现。

可以使用关键字-选项/值对调用 pack() 方法,这些对控制小部件在其容器中的显示位置,以及在调整主应用程序窗口大小时的行为方式。 这里有些例子:

fred.pack()                     # defaults to side = "top"
fred.pack(side="left")
fred.pack(expand=1)

封隔器选项

有关加壳程序及其可以采用的选项的更多信息,请参阅手册页和 John Ousterhout 的书的第 183 页。

锚型。 表示包装工将每个奴隶放置在其包裹中的位置。
扩张
布尔值,01
充满
合法值:'x''y''both''none'
ipadx 和 ipady
距离 - 在从属部件的每一侧指定内部填充。
padx 和 pady
距离 - 在从属部件的每一侧指定外部填充。
合法值为:'left''right''top''bottom'


耦合小部件变量

某些小部件(如文本输入小部件)的当前值设置可以通过使用特殊选项直接连接到应用程序变量。 这些选项是 variabletextvariableonvalueoffvaluevalue。 这种连接是双向的:如果变量因任何原因发生变化,它所连接的小部件将更新以反映新值。

不幸的是,在 tkinter 的当前实现中,不可能通过 variabletextvariable 选项将任意 Python 变量移交给小部件。 唯一可以使用的变量类型是从名为 Variable 的类派生的变量,该类在 tkinter 中定义。

已经定义了许多有用的 Variable 子类:StringVarIntVarDoubleVarBooleanVar。 要读取此类变量的当前值,请对其调用 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 选项数据类型

合法值是罗盘的点数:"n""ne""e""se""s""sw""w""nw" 以及 "center"

位图

有八个内置的命名位图:'error''gray25''gray50''hourglass''info''questhead' ]、'question''warning'。 要指定 X 位图文件名,请提供文件的完整路径,并以 @ 开头,如 "@/usr/contrib/bitmap/gumby.bit"

布尔值

您可以传递整数 0 或 1 或字符串 "yes""no"

打回来

这是任何不带参数的 Python 函数。 例如:

def print_it():
    print("hi there")
fred["command"] = print_it
颜色

颜色可以是 rgb.txt 文件中 X 颜色的名称,也可以是表示 4 位 RGB 值的字符串:"#RGB",8 位:"#RRGGBB",12 位”"#RRRGGGBBB" 或 16 位 "#RRRRGGGGBBBB" 范围,其中 R、G、B 表示任何合法的十六进制数字。 有关详细信息,请参阅 Ousterhout 书中的第 160 页。

光标

可以使用来自 cursorfont.h 的标准 X 光标名称,无需 XC_ 前缀。 例如,要获得手形光标 (XC_hand2),请使用字符串 "hand2"。 您还可以指定自己的位图和遮罩文件。 参见 Ousterhout 书中的第 179 页。

距离

屏幕距离可以以像素或绝对距离指定。 像素以数字形式给出,绝对距离以字符串形式给出,尾随字符表示单位:c 表示厘米,i 表示英寸,m 表示毫米,p ] 为打印机点数。 例如,3.5 英寸表示为 "3.5i"

字体

Tk 使用列表字体名称格式,例如 {courier 10 bold}。 带有正数的字体大小以磅为单位; 带有负数的尺寸以像素为单位。

几何学

这是一个格式为 widthxheight 的字符串,其中大多数小部件的宽度和高度以像素为单位(显示文本的小部件以字符为单位)。 例如:fred["geometry"] = "200x100"

证明合法

合法值为字符串:"left""center""right""fill"

地区

这是一个包含四个以空格分隔的元素的字符串,每个元素都是一个合法的距离(见上文)。 例如:"2 3 4 5""3i 2i 4.5i 2i""3c 2c 4c 10.43c" 都是合法的区域。

宽慰

确定小部件的边框样式。 合法值为:"raised""sunken""flat""groove""ridge"

滚动命令

这几乎总是某些滚动条小部件的 set() 方法,但可以是任何接受单个参数的小部件方法。

必须是以下之一:"none""char""word"


绑定和事件

小部件命令中的 bind 方法允许您监视某些事件并在该事件类型发生时触发回调函数。 bind方法的形式为:

def bind(self, sequence, func, add=''):

在哪里:

顺序
是一个字符串,表示事件的目标类型。 (有关详细信息,请参阅 John Ousterhout 的书的 bind 手册页和第 201 页)。
功能
是一个 Python 函数,带有一个参数,在事件发生时被调用。 Event 实例将作为参数传递。 (以这种方式部署的函数通常称为 callbacks。)
添加
是可选的,可以是 '+'。 传递空字符串表示此绑定将替换与此事件关联的任何其他绑定。 传递一个 '+' 意味着这个函数将被添加到绑定到这个事件类型的函数列表中。

例如:

def turn_red(self, event):
    event.widget["activeforeground"] = "red"

self.button.bind("<Enter>", self.turn_red)

请注意如何在 turn_red() 回调中访问事件的小部件字段。 此字段包含捕获 X 事件的小部件。 下表列出了您可以访问的其他事件字段,以及它们在 Tk 中的表示方式,这在参考 Tk 手册页时非常有用。

TK Tkinter 事件字段 TK Tkinter 事件字段
%f 重点 %一种 字符
%H 高度 %E 发送事件
%k 关键代码 %K 键符
%s 状态 %N keysym_num
%t 时间 %T 类型
%w 宽度 %W 小部件
%x x %X x_root
%y y %Y y_root


索引参数

许多小部件需要传递“索引”参数。 它们用于指向 Text 小部件中的特定位置,或 Entry 小部件中的特定字符,或 Menu 小部件中的特定菜单项。

条目小部件索引(索引、视图索引等)
条目小部件具有指代正在显示的文本中的字符位置的选项。 您可以使用这些 tkinter 函数来访问文本小部件中的这些特殊点:
文本小部件索引
Text 小部件的索引符号非常丰富,在 Tk 手册页中得到了最好的描述。
菜单索引(menu.invoke(), menu.entryconfig() 等)
菜单的一些选项和方法操作特定的菜单条目。 任何时候选项或参数需要菜单索引时,您都可以传入:
  • 一个整数,它指的是小部件中条目的数字位置,从顶部开始计数,从 0 开始;
  • 字符串"active",指的是当前光标所在的菜单位置;
  • 字符串 "last" 指的是最后一个菜单项;
  • 前面有 @ 的整数,如 @6,其中整数被解释为菜单坐标系中的 y 像素坐标;
  • 字符串 "none",表示根本没有菜单条目,最常与 menu.activate() 一起使用以停用所有条目,最后,
  • 从菜单顶部到底部扫描的与菜单条目标签匹配的文本字符串。 请注意,此索引类型是在所有其他类型之后考虑的,这意味着匹配标记为 lastactivenone 的菜单项可能会被解释为上述文字,而不是.


图片

通过tkinter.Image对应的子类可以创建不同格式的图片:

  • BitmapImage 用于 XBM 格式的图像。
  • PhotoImage 适用于 PGM、PPM、GIF 和 PNG 格式的图像。 从 Tk 8.6 开始支持后者。

任一类型的图像都是通过 filedata 选项创建的(其他选项也可用)。

然后可以在某些小部件支持 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 上不可用。

由于您不知道有多少字节可供读取,您可能不想使用 BufferedIOBaseTextIOBase read()readline () 方法,因为这些方法会坚持读取预定义的字节数。 对于套接字,recv()recvfrom() 方法可以正常工作; 对于其他文件,使用原始读取或 os.read(file.fileno(), maxbytecount)

Widget.tk.createfilehandler(file, mask, func)

注册文件处理回调函数 funcfile 参数可以是具有 fileno() 方法的对象(例如文件或套接字对象),也可以是整数文件描述符。 mask 参数是以下三个常量中任何一个的 ORed 组合。 回调调用如下:

callback(file, mask)
Widget.tk.deletefilehandler(file)
取消注册文件处理程序。
tkinter.READABLE

tkinter.WRITABLE
tkinter.EXCEPTION

mask 参数中使用的常量。