25.1. tkinter
— Tcl/Tk的Python接口¶
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映射到Tkinter 中 tkinter
相当于以下内容的部分。)
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 |
选项名称 |
|
1 |
数据库查找的选项名称 |
|
2 |
数据库查找的选项类 |
|
3 |
默认值 |
|
4 |
当前值 |
|
例:
>>> 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页。
- 锚
锚类型。表示打包机将每个从站放在其包裹中的位置。
- 扩大
布尔,
0
或1
。- 填
法律价值观:
'x'
,'y'
,'both'
,'none'
。- ipad和ipad
距离 - 在从属小部件的每一侧指定内部填充。
- padx和pady
距离 - 在从属小部件的每一侧指定外部填充。
- 侧
法律价值是:
'left'
,'right'
,'top'
,'bottom'
。
25.1.6.4. 耦合小部件变量¶
一些小部件(例如文本输入小部件)的当前值设置可以通过使用特殊选项直接连接到应用程序变量。这些选项是 variable
,textvariable
,onvalue
,offvalue
和 value
。此连接的工作方式有两种:如果变量因任何原因更改,则其连接到的窗口小部件将更新以反映新值。
不幸的是,在当前 tkinter
的实现中,不可能通过 variable
或 textvariable
选项将任意的Python变量移交给窗口部件。唯一适用于这种变量的变量是从 tkinter
中定义的变量类中子类化的变量。
有很多有用的变量子类:StringVar
,IntVar
,DoubleVar
和 BooleanVar
。要读取这样一个变量的当前值,调用它的 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()来停用所有条目,最后,从菜单顶部到底部扫描的与菜单条目的标签匹配的文本字符串。注意,在所有其他之后考虑该索引类型,这意味着标记为
last
,active
或none
的菜单项的匹配可以被解释为上述文字。
25.1.6.9. 图片¶
位图/像素映射图像可以通过 tkinter.Image
的子类创建:
BitmapImage
可用于X11位图数据。PhotoImage
可用于GIF和PPM/PGM颜色位图。
通过 file
或 data
选项(其他选项也可用)创建任一类型的图像。
然后可以在某些小部件支持 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上不可用。
由于您不知道有多少字节可用于读取,您可能不想使用 BufferedIOBase
或 TextIOBase
read()
或 readline()
方法,因为这些方法将坚持读取预定义数量的字节。对于套接字,recv()
或 recvfrom()
方法将正常工作;对于其他文件,使用原始读取或 os.read(file.fileno(), maxbytecount)
。
-
Widget.tk.
createfilehandler
(file, mask, func)¶ 注册文件处理程序回调函数 func。 file 参数可以是具有
fileno()
方法的对象(例如文件或套接字对象)或整数文件描述符。 mask 参数是以下三个常量中的任何一个的ORed组合。回调的调用如下:callback(file, mask)
-
Widget.tk.
deletefilehandler
(file)¶ 取消注册文件处理程序。