Skip to main content

25.1. tkinter — Tcl/Tk的Python接口

源代码: Lib/tkinter/__init__.py


tkinter 包(“Tk接口”)是Tk GUI工具包的标准Python接口。 Tk和 tkinter 在大多数Unix平台以及Windows系统上都可用。 (Tk本身不是Python的一部分;它在ActiveState中维护。)您可以通过从命令行运行 python -m tkinter 来检查 tkinter 是否已正确安装在系统上;这应该打开一个窗口演示一个简单的Tk接口。

参见

Python Tkinter资源

Python Tkinter主题指南提供了大量关于从Python使用Tk并链接到Tk上的其他信息源的信息。

TKDocs

广泛的教程加上友好的小部件页面的一些小部件。

Tkinter引用:Python的GUI

在线参考材料。

Tokinter docs from effbot

tbot的在线参考由effbot.org支持。

Tcl/Tk手册

最新的tcl/tk版本的官方手册。

编程Python

本书由Mark Lutz编写,拥有Tkinter的良好覆盖。

繁忙的Python开发人员的现代Tkinter

由Mark Rozerman撰写的关于使用Python和Tkinter构建有吸引力和现代图形用户界面的书。

Python和Tkinter编程

这本书由约翰·格雷森(ISBN 1-884777-81-3)。

25.1.1. Tkinter模块

大多数时候,tkinter 是你真正需要的,但也有一些额外的模块。 Tk接口位于名为 _tkinter 的二进制模块中。该模块包含对Tk的低级接口,并且不应该被应用程序员直接使用。它通常是共享库(或DLL),但在某些情况下可能与Python解释器静态链接。

除了Tk接口模块之外,tkinter 还包括一些Python模块,tkinter.constants 是最重要的之一。导入 tkinter 将自动导入 tkinter.constants,所以,通常,使用Tkinter所有你需要的是一个简单的import语句:

import tkinter

或者,更频繁:

from tkinter import *
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() 方法创建一个Toplevel窗口(并且初始化Tk子系统)。

提供Tk支持的其他模块包括:

tkinter.scrolledtext

文本小部件与内置的垂直滚动条。

tkinter.colorchooser

对话框让用户选择一种颜色。

tkinter.commondialog

在此处列出的其他模块中定义的对话框的基类。

tkinter.filedialog

通用对话框允许用户指定要打开或保存的文件。

tkinter.font

帮助使用字体的实用程序。

tkinter.messagebox

访问标准Tk对话框。

tkinter.simpledialog

基本对话框和方便功能。

tkinter.dnd

tkinter 的拖放支持。这是实验性的,应该在它被Tk DND替换时被弃用。

turtle

乌龟图形在Tk窗口。

25.1.2. Tkinter救生衣

本节不是为Tk或Tkinter提供详尽的教程。相反,其旨在作为停止间隙,在系统上提供一些介绍性取向。

积分:

  • Tk是由John Ousterhout在伯克利时写的。

  • Tkinter是由Steen Lumholt和Guido van Rossum写的。

  • 这个救生员是由弗吉尼亚大学的马特·康威(Matt Conway)写的。

  • HTML渲染和一些自由编辑,是由Ken Manheimer的FrameMaker版本生成的。

  • Fredrik Lundh详细阐述和修改了类接口描述,以使它们与Tk 4.2一起使用。

  • Mike Clarkson将文档转换为LaTeX,并编译了参考手册的用户界面一章。

25.1.2.1. 如何使用本节

这部分设计分为两部分:前半部分(大致)覆盖背景材料,而后半部分可以取到键盘作为方便的参考。

当试图回答“我如何做blah”的形式的问题时,通常最好找出如何在直的Tk中做“blah”,然后将其转换回相应的 tkinter 呼叫。 Python程序员经常可以通过查看Tk文档来猜测正确的Python命令。这意味着,为了使用Tkinter,你将不得不知道一点关于Tk。此文档不能履行该角色,因此我们能做的最好的是指向存在的最好的文档。这里有一些提示:

  • 作者强烈建议获取Tk手册页的副本。具体来说,manN 目录中的手册页是最有用的。 man3 手册页描述了到Tk库的C接口,因此对于脚本编写者不是特别有用。

  • Addison-Wesley出版了一本名为Tcl和Tk Toolkit的书,作者是John Ousterhout(ISBN 0-201-63337-X),这是对新手Tcl和Tk的一个很好的介绍。这本书不是详尽无遗,对于许多细节,它推迟到手册页。

  • tkinter/__init__.py 是大多数的最后的手段,但可以是一个好地方去,当没有其他有意义。

参见

Tcl/Tk 8.6手册页

Tcl/Tk手册www.tcl.tk.

ActiveState Tcl主页

Tk/Tcl开发主要发生在ActiveState。

Tcl和Tk工具包

这本书由约翰·奥斯特豪特,Tcl的发明家。

Tcl和Tk中的实践编程

布伦特·韦尔奇的百科全书。

25.1.2.2. 一个简单的Hello World程序

import tkinter as tk

class Application(tk.Frame):
    def __init__(self, master=None):
        super().__init__(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=root.destroy)
        self.quit.pack(side="bottom")

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

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

25.1.3. A(非常)快速看看Tcl/Tk

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

笔记:

  • 这些类是为了在一个命名空间下组织某些功能而提供的。它们不是要独立实例化。

  • Tk 类仅在应用程序中实例化一次。应用程序程序员不需要显式地实例化一个,只要任何其他类被实例化,系统就创建一个。

  • Widget 类不是实例化的,它只是用于子类化以产生“真实”小部件(在C++中,这被称为“抽象类”)。

为了利用这个参考资料,有时你需要知道如何阅读Tk的短篇,以及如何识别Tk命令的各个部分。 (请参阅 将基本Tk映射到Tkintertkinter 相当于以下内容的部分。)

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

要在Tk中创建一个窗口小部件,命令总是具有形式:

classCommand newPathname options
classCommand

表示要进行哪种类型的小部件(按钮,标签,菜单...)

newPathname

是这个小部件的新名称。 Tk中的所有名称必须是唯一的。为了帮助实现这一点,Tk中的窗口小部件使用 pathnames 命名,就像文件系统中的文件一样。顶级窗口小部件(root)称为 . (句点),子句由更多句点分隔。例如,.myApp.controlPanel.okButton 可能是窗口小部件的名称。

options

配置窗口小部件的外观,在某些情况下配置其行为。选项以标志和值的列表的形式出现。标志前面是一个“ - ”,像Unix shell命令标志,如果值超过一个字,值将被置于引号中。

例如:

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

创建后,窗口小部件的路径名将成为新命令。这个新的 widget命令 是程序员的处理,让新的小部件执行一些 action。在C中,你可以表示为someAction(fred,someOptions),在C++中,你可以表示为fred.someAction(someOptions),在Tk中,你说:

.fred someAction someOptions

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

正如你所期望的,someAction 的合法值将取决于窗口小部件的类:.fred disable 工作,如果fred是一个按钮(fred变灰),但不工作,如果fred是一个标签(禁用标签不支持Tk )。

someOptions 的法律价值取决于行动。某些操作(如 disable)不需要任何参数,其他操作(如文本输入框的 delete 命令)则需要参数来指定要删除的文本范围。

25.1.4. 将基本Tk映射到Tkinter

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

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

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

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

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

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")

25.1.6. 方便的参考

25.1.6.1. 设置选项

选项控制像窗口部件的颜色和边框宽度。选项可以通过三种方式设置:

在对象创建时,使用关键字参数
fred = Button(self, fg="red", bg="blue")
创建对象后,像字典索引一样处理选项名称
fred["fg"] = "red"
fred["bg"] = "blue"
使用config()方法在对象创建后更新多个attrs
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')}

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

25.1.6.2. 封隔器

封装器是Tk的几何管理机制之一。几何管理器用于指定小部件在其容器中的定位的相对定位 - 它们的相互 master。与更麻烦的 placer (这是较不常用的,我们不在这里覆盖)相反,打包器采取定性关系规范–above到左侧filling 等 - 并做出一切,以确定确切的位置坐标为您。

任何 master 小部件的大小由“从属小部件”的大小确定。打包程序用于控制从属小部件在打包的主机中出现的位置。您可以将窗口小部件包装到框架中,将框架包装到其他框架中,以便实现所需的布局。此外,该装置被动态地调整以适应配置的增量变化,一旦被包装。

请注意,小部件不会出现,直到他们已经使用几何管理器指定其几何。这是一个常见的早期错误,忽略几何规范,然后惊讶当窗口小部件创建,但没有出现。窗口小部件只有在它应用了封装器的 pack() 方法之后才会出现。

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

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

25.1.6.3. 封隔器选项

有关包装商及其可选择的更多信息,请参阅John Ousterhout的书的手册页和第183页。

锚类型。表示打包机将每个从站放在其包裹中的位置。

扩大

布尔,01

法律价值观:'x''y''both''none'

ipad和ipad

距离 - 在从属小部件的每一侧指定内部填充。

padx和pady

距离 - 在从属小部件的每一侧指定外部填充。

法律价值是:'left''right''top''bottom'

25.1.6.4. 耦合小部件变量

一些小部件(例如文本输入小部件)的当前值设置可以通过使用特殊选项直接连接到应用程序变量。这些选项是 variabletextvariableonvalueoffvaluevalue。此连接的工作方式有两种:如果变量因任何原因更改,则其连接到的窗口小部件将更新以反映新值。

不幸的是,在当前 tkinter 的实现中,不可能通过 variabletextvariable 选项将任意的Python变量移交给窗口部件。唯一适用于这种变量的变量是从 tkinter 中定义的变量类中子类化的变量。

有很多有用的变量子类:StringVarIntVarDoubleVarBooleanVar。要读取这样一个变量的当前值,调用它的 get() 方法,并改变它的值,调用 set() 方法。如果你遵循这个协议,小部件将始终跟踪变量的值,您没有进一步干预。

例如:

class App(Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.pack()

        self.entrythingy = Entry()
        self.entrythingy.pack()

        # here is the application variable
        self.contents = 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

        # and here we get a callback when the user hits return.
        # we will have the program print out the value of the
        # application variable when the user hits return
        self.entrythingy.bind('<Key-Return>',
                              self.print_contents)

    def print_contents(self, event):
        print("hi. contents of entry is now ---->",
              self.contents.get())

25.1.6.5. 窗口管理器

在Tk中,有一个实用程序命令 wm,用于与窗口管理器交互。 wm 命令的选项允许您控制诸如标题,位置,图标位图等。在 tkinter 中,这些命令已经实现为 Wm 类上的方法。 Toplevel小部件是从 Wm 类进行子类化的,因此可以直接调用 Wm 方法。

要获取包含给定小部件的顶层窗口,您通常可以参考小部件的主控。当然,如果窗口小部件已经在框架中打包,则主窗口将不表示顶层窗口。要获取包含任意窗口小部件的toplevel窗口,可以调用 _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()

25.1.6.6. 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"

scrollcommand

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

包:

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

25.1.6.7. 绑定和事件

widget命令的绑定方法允许您监视某些事件,并在发生事件类型时触发回调函数。绑定方法的形式是:

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

哪里:

序列

是表示事件的目标类型的字符串。 (有关详细信息,请参阅John Ousterhout的书的bind手册页和第201页)。

func

是一个Python函数,使用一个参数,在事件发生时调用。事件实例将作为参数传递。 (这种部署的函数通常称为 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

焦点

%一个

char

%H

高度

%E

send_event

%k

关键代码

%K

keysym

%s

%N

keysym_num

%t

时间

%T

类型

%w

宽度

%W

窗口小部件

%X

X

%X

x_root

%y

y

%Y

y_root

25.1.6.8. 索引参数

许多小部件需要传递“索引”参数。这些用于指向文本小部件中的特定位置,或者指向Entry小部件中的特定字符,或指向菜单小部件中的特定菜单项。

条目窗口小部件索引(索引,视图索引等)

条目小部件具有指向正在显示的文本中的字符位置的选项。您可以使用这些 tkinter 函数访问文本小部件中的这些特殊点:

文本窗口小部件索引

Text小部件的索引符号非常丰富,最好在Tk手册页中进行描述。

菜单索引(menu.invoke(),menu.entryconfig()等)

菜单的一些选项和方法操纵特定的菜单项。每当选项或参数需要菜单索引时,您可以传入:

  • 一个整数,指的是窗口小部件中条目的数字位置,从顶部开始,从0开始;

  • 字符串 "active",其指当前在光标下的菜单位置;

  • 参考最后一个菜单项的字符串 "last"

  • 前面有 @ 的整数,如 @6,其中整数被解释为菜单坐标系中的y像素坐标;

  • 字符串 "none",它表示根本没有菜单项,最常用于menu.activate()来停用所有条目,最后,

  • 从菜单顶部到底部扫描的与菜单条目的标签匹配的文本字符串。注意,在所有其他之后考虑该索引类型,这意味着标记为 lastactivenone 的菜单项的匹配可以被解释为上述文字。

25.1.6.9. 图片

位图/像素映射图像可以通过 tkinter.Image 的子类创建:

  • BitmapImage 可用于X11位图数据。

  • PhotoImage 可用于GIF和PPM/PGM颜色位图。

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

然后可以在某些小部件支持 image 选项(例如,标签,按钮,菜单)的任何地方使用图像对象。在这些情况下,Tk不会保留对图像的引用。当对图像对象的最后一个Python引用被删除时,图像数据也被删除,并且Tk将在图像被使用的任何地方显示一个空框。

25.1.7. 文件处理程序

Tk允许注册和取消注册一个回调函数,当文件描述符上可能有I/O时,它将从Tk mainloop中调用。每个文件描述符只能注册一个处理程序。示例代码:

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 参数中使用的常量。