24.1. Tkinter — Tcl/Tk 的 Python 接口

Tkinter模块(“ Tk 接口”)是 Tk GUI 工具包的标准 Python 接口。 Tk 和Tkinter在大多数 Unix 平台以及 Windows 系统上都可用。 (Tk 本身不是 Python 的一部分;它在 ActiveState 中维护.)

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

Note

Tkinter在 Python 3 中已重命名为tkinter。在将源转换为 Python 3 时,2to3工具将自动适应导入。

See also

Tkinter documentation:

Tcl/Tk documentation:

24.1.1. Tkinter 模块

在大多数情况下,Tkinter模块是您 true 需要的,但也可以使用许多其他模块。 Tk 接口位于名为_tkinter的二进制模块中。该模块包含到 Tk 的低级接口,并且绝对不能被应用程序程序员直接使用。它通常是一个共享库(或 DLL),但在某些情况下可能与 Python 解释器静态链接。

Tkinter除了 Tk 接口模块外,还包括许多 Python 模块。两个最重要的模块是Tkinter模块本身和一个名为Tkconstants的模块。前者自动导入后者,因此要使用 Tkinter,您需要做的就是导入一个模块:

import Tkinter

或者,更常见的是:

from Tkinter import *
    • class * Tkinter. Tk(* screenName = None baseName = None className ='Tk' useTk = 1 *)
    • 实例Tk类不带参数。这将创建 Tk 的顶级窗口小部件,该窗口小部件通常是应用程序的主窗口。每个实例都有其自己关联的 Tcl 解释器。

在版本 2.4 中更改:添加了* useTk *参数。

  • Tkinter. Tcl(* screenName = None baseName = None className ='Tk' useTk = 0 *)
    • Tcl()函数是一种工厂函数,它创建与Tk类创建的对象非常相似的对象,不同之处在于它不初始化 Tk 子系统。在一个不想创建多余的顶层窗口或一个不能创建多余的顶级窗口的环境(例如,没有 X 服务器的 Unix/Linux 系统)中驱动 Tcl 解释器时,这通常很有用。passTcl()对象创建的对象可以pass调用其loadtk()方法来创建顶级窗口(并初始化 Tk 子系统)。

2.4 版的新Function。

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

  • ScrolledText

    • 具有内置垂直滚动条的文本小部件。
  • tkColorChooser

    • 允许用户选择颜色的对话框。
  • tkCommonDialog

    • 在此处列出的其他模块中定义的对话框的 Base Class。
  • tkFileDialog

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

    • 用于处理字体的 Util。
  • tkMessageBox

    • 访问标准 Tk 对话框。
  • tkSimpleDialog

    • 基本对话框和便利Function。
  • Tkdnd

    • Tkinter的拖放支持。这是实验性的,当用 Tk DND 替换时,不建议使用。
  • turtle

    • 在 Tk 窗口中显示图形。

这些在 Python 3 中也已重命名;它们都是新tkinter包的子模块。

24.1.2. Tkinter 救生衣

本部分的目的不是在 Tk 或 Tkinter 上提供详尽的教程。相反,它旨在作为一个停止间隙,在系统上提供一些介绍性的方向。

Credits:

  • Tkinter 由 Steen Lumholt 和 Guido van Rossum 撰写。

  • Tk 是在伯克利任职期间由 John Ousterhout 撰写的。

  • 这本《生命保存者》是弗吉尼亚大学的马特·康威(Matt Conway)撰写的。

  • html 渲染和一些自由编辑由 Ken Manheimer 从 FrameMaker 版本产生。

  • Fredrik Lundh 阐述并修订了类接口说明,以使它们与 Tk 4.2 保持一致。

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

24.1.2.1. 如何使用本节

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

try回答“我该怎么办”的形式的问题时,通常最好找出直行 Tk 中的“等等”,然后将其转换回相应的Tkinter调用。 Python 程序员通常可以pass查看 Tk 文档来猜测正确的 Python 命令。这意味着要使用 Tkinter,您将必须对 Tk 有所了解。该文档不能发挥该作用,因此我们能做的最好的就是将您指向存在的最佳文档。这里有一些提示:

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

  • Addison-Wesley 出版了 John Ousterhout 撰写的名为 Tcl 和 Tk 工具包的书(ISBN 0-201-63337-X),对于新手来说,这是对 Tcl 和 Tk 的很好的介绍。这本书不是详尽无遗的,并且对于许多细节而言,它都遵循手册页。

  • Tkinter.py是大多数人的最后选择,但是当没有其他意义时,它可能是一个不错的选择。

24.1.2.2. 一个简单的 Hello World 程序

from Tkinter import *

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

    def createWidgets(self):
        self.QUIT = Button(self)
        self.QUIT["text"] = "QUIT"
        self.QUIT["fg"]   = "red"
        self.QUIT["command"] =  self.quit

        self.QUIT.pack({"side": "left"})

        self.hi_there = Button(self)
        self.hi_there["text"] = "Hello",
        self.hi_there["command"] = self.say_hi

        self.hi_there.pack({"side": "left"})

    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        self.createWidgets()

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

24.1.3. 快速了解 Tcl/Tk

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

Notes:

  • 提供这些类是为了在一个名称空间下组织某些Function。它们并不是要独立实例化。

  • Tk类只能在应用程序中实例化一次。应用程序程序员无需显式实例化一个实例,每当实例化任何其他类时,系统都会创建一个实例。

  • Widget类不是要实例化的,它仅意味着要进行子类化以制作“真实的”小部件(在 C 中,这称为“抽象类”)。

为了利用此参考资料,有时您需要了解如何阅读 Tk 的短文以及如何识别 Tk 命令的各个部分。 (有关以下内容的Tkinter等效信息,请参见将基本 TkMap 到 Tkinter部分。)

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

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

classCommand newPathname options
  • classCommand

    • 表示要制作哪种小部件(按钮,标签,菜单…)
  • newPathname

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

    • 配置小部件的外观,并在某些情况下配置其行为。选项以标志和值列表的形式出现。与 Unix shell 命令标志一样,标志前面带有“-”,如果值不止一个字,则将值放在引号中。

For example:

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)不需要参数,而其他动作(例如文本 Importing 框的delete命令)则需要参数来指定要删除的文本范围。

24.1.4. 将基本 TkMap 到 Tkinter

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

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

在创建时,对象的主体隐含在为其赋予的新名称中。在 Tkinter 中,显式指定了母版。

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

Tk 中的配置选项在连字符标签列表中给出,后跟数值。在 Tkinter 中,选项在实例构造函数中指定为关键字参数,而在配置调用中指定关键字-args 用于配置调用,或在字典样式中指定为实例索引。有关设置选项,请参见第Setting Options节。

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

在 Tk 中,要对窗口小部件执行操作,请使用窗口小部件名称作为命令,并在其后加上操作名称,可能还带有参数(选项)。在 Tkinter 中,您可以在类实例上调用方法来调用小部件上的操作。 Tkinter.py 模块中列出了给定窗口小部件可以执行的操作(方法)。

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

要将小部件提供给打包程序(几何 Management 器),请调用带有可选参数的 pack。在 Tkinter 中,Pack 类拥有所有这些Function,并且 pack 命令的各种形式都作为方法来实现。 Tkinter中的所有小部件都从 Packer 继承而来,因此继承了所有包装方法。有关表单几何 Management 器的其他信息,请参见Tix模块文档。

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

24.1.5. Tk 和 Tkinter 的关系

从上到下:

24.1.6. 方便参考

24.1.6.1. 设定选项

选项控制诸如小部件的颜色和边框宽度之类的东西。可以pass三种方式设置选项:

  • 在对象创建时,使用关键字参数

fred = Button(自我,fg =“红色”,bg =“蓝色”)


 - After object creation, treating the option name like a dictionary index

   - ```default
fred["fg"] = "red"
fred["bg"] = "blue"
  • 创建对象后使用 config()方法更新多个属性

fred.config(fg =“红色”,bg =“蓝色”)


 

For a complete explanation of a given option and its behavior, see the Tk man pages for the widget in question\.

 

Note that the man pages list "STANDARD OPTIONS" and "WIDGET SPECIFIC OPTIONS" for each widget\. The former is a list of options that are common to many widgets, the latter are the options that are idiosyncratic to that particular widget\. The Standard Options are documented on the  *options\(3\)*  man page\.

 

No distinction between standard and widget\-specific options is made in this document\. Some options don't apply to some kinds of widgets\. Whether a given widget responds to a particular option depends on the class of the widget; buttons have a  `command`  option, labels do not\.

 

The options supported by a given widget are listed in that widget's man page, or can be queried at runtime by calling the  `config()`  method without arguments, or by calling the  `keys()`  method on that widget\. The return value of these calls is a dictionary whose key is the name of the option as a string \(for example,  `'relief'` \) and whose values are 5\-tuples\.

 

Some options, like  `bg`  are synonyms for common options with long names \( `bg`  is shorthand for "background"\)\. Passing the  `config()`  method the name of a shorthand option will return a 2\-tuple, not 5\-tuple\. The 2\-tuple passed back will contain the name of the synonym and the "real" option \(such as  `('bg', 'background')` \)\.

 

|Index|Meaning|Example|
|----|----|----|
|0|option name|`'relief'`|
|1|option name for database lookup|`'relief'`|
|2|option class for database lookup|`'Relief'`|
|3|default value|`'raised'`|
|4|current value|`'groove'`|

 

Example:

 

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

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

24.1.6.2. 封隔器

封隔器是 Tk 的几何 Management 机制之一。几何 Management 器用于指定窗口小部件在其容器中的相对位置-它们的相互* master 。与比较繁琐的 placer (这种用法较少见,我们不在此介绍)相比,打包机采用了定性关系规范- above 左侧的 filling *等-并可以工作一切都将为您确定确切的位置坐标。

任何* master *小部件的大小取决于内部“从属小部件”的大小。打包程序用于控制从属窗口小部件在打包它们的主窗口中出现的位置。您可以将小部件打包到框架中,也可以将框架打包到其他框架中,以实现所需的布局。此外,一旦打包,就可以动态调整该配置以适应配置的增量更改。

请注意,只有在用几何图形 Management 器指定其几何图形后,窗口小部件才会出现。遗忘几何规范,然后在创建小部件时却一无所获,这是一个常见的早期错误。窗口小部件仅在对其应用了打包程序的pack()方法后才会显示。

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

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

24.1.6.3. 封隔器选项

有关打包器及其可用选项的更多详细信息,请参见 John Ousterhout 的手册页和第 183 页。

  • anchor

    • 锚类型。指示打包程序将每个从站放置在其包裹中的位置。
  • expand

    • 布尔值01
  • fill

    • 合法值:'x''y''both''none'
  • ipadx 和 ipady

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

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

    • 合法值为:'left''right''top''bottom'

24.1.6.4. 耦合小部件变量

某些小部件(例如文本 Importing 小部件)的当前值设置可以pass使用特殊选项直接连接到应用程序变量。这些选项是variabletextvariableonvalueoffvaluevalue。这种连接有两种作用:如果变量由于任何原因发生变化,则所连接的小部件将被更新以反映新值。

不幸的是,在Tkinter的当前实现中,无法passvariabletextvariable选项将任意 Python 变量移交给小部件。唯一适用的变量是在Tkinter模块中定义的变量类的子类。

已经定义了许多有用的 Variable 子类:StringVarIntVarDoubleVarBooleanVar。要读取此类变量的当前值,请在其上调用get()方法,并passset()方法来更改其值。如果您遵循此协议,则小部件将始终跟踪变量的值,而无需您进行任何干预。

For example:

class App(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, 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()

24.1.6.5. 窗口 Management 器

在 Tk 中,有一个 Util 命令wm,用于与窗口 Management 器进行交互。 wm命令的选项使您可以控制标题,位置,图标位图等。在Tkinter中,这些命令已实现为Wm类上的方法。顶级窗口小部件是Wm类的子类,因此可以直接调用Wm方法。

要获得包含给定窗口小部件的顶层窗口,通常可以仅参考窗口小部件的主窗口。当然,如果小部件已包装在框架内,则主部件将不代表顶层窗口。要进入包含任意窗口小部件的顶层窗口,可以调用_root()方法。此方法以下划线开头,表示该Function是实现的一部分,而不是 Tk Function的接口。

以下是一些典型用法示例:

from Tkinter import *
class App(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, 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()

24.1.6.6. 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

    • 这是形式为widthxheight的字符串,其中大多数小部件的宽度和高度以像素为单位(显示文本的小部件以字符为单位)。例如: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()方法,但是可以是任何带有单个参数的小部件方法。有关示例,请参考 Python 源代码分发中的文件Demo/tkinter/matt/canvas-with-scrollbars.py
  • wrap:

    • 必须为"none""char""word"之一。

24.1.6.7. 绑定和事件

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

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

where:

  • sequence

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

    • 是一个 Python 函数,带有一个参数,在事件发生时被调用。一个 Event 实例将作为参数传递。 (以这种方式部署的Function通常称为* callbacks *.)
  • add

    • 是可选的'''+'。传递空字符串表示此绑定将替换与此事件相关联的任何其他绑定。传递'+'意味着此函数将被添加到绑定到该事件类型的函数列表中。

For example:

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

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

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

Tk      Tkinter Event Field             Tk      Tkinter Event Field
--      -------------------             --      -------------------
%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

24.1.6.8. 索引参数

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

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

    • Importing 窗口小部件具有用于引用所显示文本中字符位置的选项。您可以使用以下Tkinter函数来访问文本小部件中的这些特殊点:
  • AtEnd()

    • 指文本中的最后一个位置

    • AtInsert()

      • 指文本光标所在的点
    • AtSelFirst()

      • 指示所选文本的起点
    • AtSelLast()

      • 表示所选文本的最后一点,最后
    • At(x[, y])

      • 指的是像素位置* x y 处的字符(在文本 Importing 小部件(其中包含一行文本)中不使用 y *)。
  • 文本小部件索引

    • 文本小部件的索引符号非常丰富,最好在 Tk 手册页中进行描述。
  • 菜单索引(menu.invoke(),menu.entryconfig()等)

    • 菜单的某些选项和方法可操纵特定的菜单项。每当选项或参数需要菜单索引时,您都可以传递:
  • 一个整数,指的是小部件中条目的数字位置,从顶部开始计算,从 0 开始;

  • 字符串'active',指的是当前光标所在的菜单位置;

  • 字符串"last",它指向最后一个菜单项;

  • @6一样,以@开头的整数,其中该整数在菜单的坐标系中解释为 y 像素坐标;

  • 字符串"none",表示根本没有菜单条目,最常与 menu.activate()结合使用以停用所有条目,最后,

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

24.1.6.9. Images

可以passTkinter.Image的相应子类创建不同格式的图像:

  • BitmapImage用于 XBM 格式的图像。

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

可以passfiledata选项创建任何一种图像(也可以使用其他选项)。

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

See also

Pillow软件包增加了对 BMP,JPEG,TIFF 和 WebP 等格式的支持。

24.1.7. 文件处理程序

Tk 允许您注册和注销一个回调函数,当在文件 Descriptors 上可以进行 I/O 时,将从 Tk 主循环调用该函数。每个文件 Descriptors 只能注册一个处理程序。示例代码:

import Tkinter
widget = Tkinter.Tk()
mask = Tkinter.READABLE | Tkinter.WRITABLE
widget.tk.createfilehandler(file, mask, callback)
...
widget.tk.deletefilehandler(file)

此Function在 Windows 上不可用。

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

  • Widget.tk. createfilehandler(* file mask func *)
    • 注册文件处理程序回调函数* func *。 * file *参数可以是具有fileno()方法的对象(例如文件或套接字对象),也可以是整数文件 Descriptors。 * mask *参数是以下三个常量中的任何一个的 ORed 组合。回调调用如下:
callback(file, mask)
  • Widget.tk. deletefilehandler(* file *)

    • 取消注册文件处理程序。
  • Tkinter. READABLE

  • Tkinter. WRITABLE

  • Tkinter. EXCEPTION

      • mask *参数中使用的常量。