tkinter
— Python interface to Tcl/TkTcl/Tk的Python接口¶
Source code: Lib/tkinter/__init__.py
The tkinter
package (“Tk interface”) is the standard Python interface to the Tcl/Tk GUI toolkit. tkinter
包(“Tk接口”)是Tcl/Tk GUI工具包的标准Python接口。Both Tk and Tk和tkinter
are available on most Unix platforms, including macOS, as well as on Windows systems.tkinter
在大多数Unix平台上都可用,包括macOS和Windows系统。
Running 从命令行运行python -m tkinter
from the command line should open a window demonstrating a simple Tk interface, letting you know that tkinter
is properly installed on your system, and also showing what version of Tcl/Tk is installed, so you can read the Tcl/Tk documentation specific to that version.python -m tkinter
应该会打开一个窗口,演示一个简单的Tk界面,让您知道tkinter
已正确安装在您的系统上,并显示安装了哪个版本的Tcl/Tk,因此您可以阅读特定于该版本的Tcl/Tk文档。
Tkinter supports a range of Tcl/Tk versions, built either with or without thread support. Tkinter支持一系列Tcl/Tk版本,无论是否有线程支持。The official Python binary release bundles Tcl/Tk 8.6 threaded. 官方Python二进制版本捆绑了Tcl/Tk 8.6线程。See the source code for the 有关受支持版本的更多信息,请参阅_tkinter
module for more information about supported versions._tkinter
模块的源代码。
Tkinter is not a thin wrapper, but adds a fair amount of its own logic to make the experience more pythonic. Tkinter并不是一个很薄的包装器,但它添加了大量自己的逻辑,使体验更具python风格。This documentation will concentrate on these additions and changes, and refer to the official Tcl/Tk documentation for details that are unchanged.本文档将重点介绍这些添加和更改,并参考Tcl/Tk官方文档了解未更改的详细信息。
Note
Tcl/Tk 8.5 (2007) introduced a modern set of themed user interface components along with a new API to use them. Tcl/Tk 8.5(2007)引入了一组现代的主题用户界面组件,以及使用它们的新API。Both old and new APIs are still available. 新旧API仍然可用。Most documentation you will find online still uses the old API and can be woefully outdated.您可以在网上找到的大多数文档仍然使用旧的API,而且可能已经过时。
See also
- TkDocs
Extensive tutorial on creating user interfaces with Tkinter.关于使用Tkinter创建用户界面的详细教程。Explains key concepts, and illustrates recommended approaches using the modern API.解释关键概念,并说明使用现代API的推荐方法。
Tkinter 8.5 reference: a GUI for PythonTkinter 8.5参考:Python的GUIReference documentation for Tkinter 8.5 detailing available classes, methods, and options.Tkinter 8.5的参考文档详细说明了可用的类、方法和选项。
Tcl/Tk Resources:
- Tk commands
Comprehensive reference to each of the underlying Tcl/Tk commands used by Tkinter.全面参考Tkinter使用的每个底层Tcl/Tk命令。
- Tcl/Tk Home Page
Additional documentation, and links to Tcl/Tk core development.其他文档,以及指向Tcl/Tk核心开发的链接。
Books:
Modern Tkinter for Busy Python Developers面向繁忙Python开发人员的现代TkinterBy Mark Roseman. (ISBN 978-1999149567)
Python and Tkinter ProgrammingPython和Tkinter编程By Alan Moore. (ISBN 978-1788835886)
Programming PythonPython编程By Mark Lutz; has excellent coverage of Tkinter. (ISBN 978-0596158101)
Tcl and the Tk Toolkit (2nd edition)Tcl和Tk工具包(第二版)By John Ousterhout, inventor of Tcl/Tk, and Ken Jones; does not cover Tkinter. (ISBN 978-0321336330)
Architecture建筑学¶
Tcl/Tk is not a single library but rather consists of a few distinct modules, each with separate functionality and its own official documentation. Tcl/Tk不是一个单一的库,而是由几个不同的模块组成,每个模块都有单独的功能和自己的官方文档。Python’s binary releases also ship an add-on module together with it.Python的二进制版本还附带了一个附加模块。
- Tcl
Tcl is a dynamic interpreted programming language, just like Python.Tcl是一种动态解释编程语言,就像Python一样。Though it can be used on its own as a general-purpose programming language, it is most commonly embedded into C applications as a scripting engine or an interface to the Tk toolkit.尽管它可以作为通用编程语言单独使用,但它通常作为脚本引擎或Tk工具包的接口嵌入到C应用程序中。The Tcl library has a C interface to create and manage one or more instances of a Tcl interpreter, run Tcl commands and scripts in those instances, and add custom commands implemented in either Tcl or C.Tcl库有一个C接口,用于创建和管理Tcl解释器的一个或多个实例,在这些实例中运行Tcl命令和脚本,并添加在Tcl或C中实现的自定义命令。Each interpreter has an event queue, and there are facilities to send events to it and process them.每个解释器都有一个事件队列,并且有向其发送事件和处理事件的设施。Unlike Python, Tcl’s execution model is designed around cooperative multitasking, and Tkinter bridges this difference (see Threading model for details).与Python不同,Tcl的执行模型是围绕协作多任务设计的,Tkinter弥补了这一差异(有关详细信息,请参阅线程模型)。- Tk
Tk is a Tcl package implemented in C that adds custom commands to create and manipulate GUI widgets.Tk是一个用C实现的Tcl包,它添加自定义命令来创建和操作GUI小部件。Each每个Tk
object embeds its own Tcl interpreter instance with Tk loaded into it.Tk
对象嵌入自己的Tcl解释器实例,并将Tk加载到其中。Tk’s widgets are very customizable, though at the cost of a dated appearance.Tk的小部件是非常可定制的,尽管代价是外观过时。Tk uses Tcl’s event queue to generate and process GUI events.Tk使用Tcl的事件队列来生成和处理GUI事件。- Ttk
Themed Tk (Ttk) is a newer family of Tk widgets that provide a much better appearance on different platforms than many of the classic Tk widgets.主题Tk(Ttk)是一个较新的Tk小部件家族,与许多经典的Tk小部件相比,它在不同的平台上提供了更好的外观。Ttk is distributed as part of Tk, starting with Tk version 8.5.Ttk作为Tk的一部分发布,从Tk版本8.5开始。Python bindings are provided in a separate module,Python绑定在单独的模块tkinter.ttk
.tkinter.ttk
中提供。
Internally, Tk and Ttk use facilities of the underlying operating system, i.e., Xlib on Unix/X11, Cocoa on macOS, GDI on Windows.在内部,Tk和Ttk使用底层操作系统的功能,即Unix/X11上的Xlib、macOS上的Cocoa、Windows上的GDI。
When your Python application uses a class in Tkinter, e.g., to create a widget, the 当Python应用程序使用Tkinter中的类(例如)来创建小部件时,tkinter
module first assembles a Tcl/Tk command string. tkinter
模块首先组装Tcl/Tk命令字符串。It passes that Tcl command string to an internal 它将Tcl命令字符串传递给内部_tkinter
binary module, which then calls the Tcl interpreter to evaluate it. _tkinter
二进制模块,然后调用Tcl解释器对其进行评估。The Tcl interpreter will then call into the Tk and/or Ttk packages, which will in turn make calls to Xlib, Cocoa, or GDI.然后Tcl解释器将调用Tk和/或Ttk包,这些包将依次调用Xlib、Cocoa或GDI。
Tkinter ModulesTkinter模块¶
Support for Tkinter is spread across several modules. 对Tkinter的支持分布在多个模块中。Most applications will need the main 大多数应用程序都需要tkinter
module, as well as the tkinter.ttk
module, which provides the modern themed widget set and API:tkinter
主模块,以及tkinter.ttk
模块,该模块提供了现代主题小部件集和API:
from tkinter import *
from tkinter import ttk
-
class
tkinter.
Tk
(screenName=None, baseName=None, className='Tk', useTk=1)¶ TheTk
class is instantiated without arguments.Tk
类是在没有参数的情况下实例化的。This creates a toplevel widget of Tk which usually is the main window of an application.这将创建一个Tk的顶级小部件,它通常是应用程序的主窗口。Each instance has its own associated Tcl interpreter.每个实例都有自己关联的Tcl解释器。
-
tkinter.
Tcl
(screenName=None, baseName=None, className='Tk', useTk=0)¶ TheTcl()
function is a factory function which creates an object much like that created by theTk
class, except that it does not initialize the Tk subsystem.Tcl()
函数是一个工厂函数,它创建的对象与Tk
类创建的对象非常相似,只是它不初始化Tk子系统。This is most often useful when driving the Tcl interpreter in an environment where one doesn’t want to create extraneous toplevel windows, or where one cannot (such as Unix/Linux systems without an X server).在不想创建无关的顶级窗口或无法创建顶级窗口的环境中(例如没有X服务器的Unix/Linux系统)驱动Tcl解释器时,这通常非常有用。An object created by theTcl()
object can have a Toplevel window created (and the Tk subsystem initialized) by calling itsloadtk()
method.Tcl()
对象创建的对象可以通过调用其loadtk()
方法创建顶层窗口(并初始化Tk子系统)。
The modules that provide Tk support include:提供Tk支持的模块包括:
tkinter
Main Tkinter module.主Tkinter模块。tkinter.colorchooser
Dialog to let the user choose a color.对话框,让用户选择颜色。tkinter.commondialog
Base class for the dialogs defined in the other modules listed here.此处列出的其他模块中定义的对话框的基类。tkinter.filedialog
Common dialogs to allow the user to specify a file to open or save.通用对话框,允许用户指定要打开或保存的文件。tkinter.font
Utilities to help work with fonts.帮助使用字体的实用程序。tkinter.messagebox
Access to standard Tk dialog boxes.访问标准Tk对话框。tkinter.scrolledtext
Text widget with a vertical scroll bar built in.内置垂直滚动条的文本小部件。tkinter.simpledialog
Basic dialogs and convenience functions.基本对话框和便利功能。tkinter.ttk
Themed widget set introduced in Tk 8.5, providing modern alternatives for many of the classic widgets in the mainTk 8.5中引入的主题小部件集,为tkinter
module.tkinter
主模块中的许多经典小部件提供了现代的替代品。
Additional modules:其他模块:
_tkinter
A binary module that contains the low-level interface to Tcl/Tk.一个二进制模块,包含到Tcl/Tk的低级接口。It is automatically imported by the main它由tkinter
module, and should never be used directly by application programmers.tkinter
主模块自动导入,应用程序程序员永远不应该直接使用它。It is usually a shared library (or DLL), but might in some cases be statically linked with the Python interpreter.它通常是一个共享库(或DLL),但在某些情况下可能与Python解释器静态链接。idlelib
Python’s Integrated Development and Learning Environment (IDLE).Python的集成开发和学习环境(IDLE)。Based on基于tkinter
.tkinter
。tkinter.constants
Symbolic constants that can be used in place of strings when passing various parameters to Tkinter calls.向Tkinter调用传递各种参数时,可以用来代替字符串的符号常量。Automatically imported by the main由主tkinter
module.tkinter
模块自动导入。tkinter.dnd
(experimental) Drag-and-drop support for(实验)tkinter
.tkinter
的拖放支持。This will become deprecated when it is replaced with the Tk DND.当它被Tk DND替换时,它将被弃用。tkinter.tix
(deprecated) An older third-party Tcl/Tk package that adds several new widgets.(已弃用)一个旧的第三方Tcl/Tk包,它添加了几个新的小部件。Better alternatives for most can be found in对于大多数人来说,更好的选择可以在tkinter.ttk
.tkinter.ttk
找到。turtle
Turtle graphics in a Tk window.Tk窗口中的海龟图形。
Tkinter Life PreserverTkinter救生衣¶
This section is not designed to be an exhaustive tutorial on either Tk or Tkinter. 本节不是关于Tk或Tkinter的详尽教程。For that, refer to one of the external resources noted earlier. 为此,请参阅前面提到的一个外部资源。Instead, this section provides a very quick orientation to what a Tkinter application looks like, identifies foundational Tk concepts, and explains how the Tkinter wrapper is structured.相反,本节非常快速地介绍了Tkinter应用程序的外观,确定了基本的Tk概念,并解释了Tkinter包装器的结构。
The remainder of this section will help you to identify the classes, methods, and options you’ll need in your Tkinter application, and where to find more detailed documentation on them, including in the official Tcl/Tk reference manual.本节的其余部分将帮助您确定Tkinter应用程序中需要的类、方法和选项,以及在哪里可以找到关于它们的更详细文档,包括在正式的Tcl/Tk参考手册中。
A Hello World ProgramHello World程序¶
We’ll start by walking through a “Hello World” application in Tkinter. 我们将首先在Tkinter中浏览一个“Hello World”应用程序。This isn’t the smallest one we could write, but has enough to illustrate some key concepts you’ll need to know.这不是我们能写的最小的一个,但足以说明您需要了解的一些关键概念。
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()
After the imports, the next line creates an instance of the 导入之后,下一行创建Tk
class, which initializes Tk and creates its associated Tcl interpreter. Tk
类的实例,该实例初始化Tk并创建其关联的Tcl解释器。It also creates a toplevel window, known as the root window, which serves as the main window of the application.它还创建一个顶级窗口,称为根窗口,作为应用程序的主窗口。
The following line creates a frame widget, which in this case will contain a label and a button we’ll create next. 下面的一行创建了一个框架小部件,在本例中,它将包含一个标签和一个按钮,我们将在下一步创建它。The frame is fit inside the root window.框架安装在根窗口内。
The next line creates a label widget holding a static text string. 下一行创建一个包含静态文本字符串的标签小部件。The grid()
method is used to specify the relative layout (position) of the label within its containing frame widget, similar to how tables in HTML work.grid()
方法用于指定标签在其包含的框架小部件中的相对布局(位置),类似于HTML中的表的工作方式。
A button widget is then created, and placed to the right of the label. 然后创建一个按钮小部件,并将其放置在标签的右侧。When pressed, it will call the 按下时,它将调用根窗口的destroy()
method of the root window.destroy()
方法。
Finally, the 最后,mainloop()
method puts everything on the display, and responds to user input until the program terminates.mainloop()
方法将所有内容都显示出来,并响应用户输入,直到程序终止。
Important Tk Concepts重要的Tk概念¶
Even this simple program illustrates the following key Tk concepts:即使是这个简单的程序也说明了以下关键的Tk概念:
- widgets
A Tkinter user interface is made up of individual widgets.Tkinter用户界面由各个widgets组成。Each widget is represented as a Python object, instantiated from classes like每个小部件都表示为一个Python对象,由ttk.Frame
,ttk.Label
, andttk.Button
.ttk.Frame
、ttk.Label
和ttk.Button
等类实例化。widget hierarchy小部件层次结构Widgets are arranged in a hierarchy.小部件按hierarchy排列。The label and button were contained within a frame, which in turn was contained within the root window.标签和按钮包含在一个框架中,而框架又包含在根窗口中。When creating each child widget, its parent widget is passed as the first argument to the widget constructor.创建每个child小部件时,其parent小部件作为第一个参数传递给小部件构造函数。configuration options配置选项Widgets have configuration options, which modify their appearance and behavior, such as the text to display in a label or button.小部件具有配置选项,可以修改其外观和行为,例如要在标签或按钮中显示的文本。Different classes of widgets will have different sets of options.不同类别的小部件将具有不同的选项集。geometry management几何图形管理Widgets aren’t automatically added to the user interface when they are created.小部件在创建时不会自动添加到用户界面。A geometry manager like类似于几何体管理器的grid
controls where in the user interface they are placed.grid
控制它们在用户界面中的位置。- event loop
Tkinter reacts to user input, changes from your program, and even refreshes the display only when actively running an event loop.Tkinter仅在主动运行事件循环时才对用户输入、程序更改做出反应,甚至刷新显示。If your program isn’t running the event loop, your user interface won’t update.如果程序未运行事件循环,则用户界面不会更新。
Understanding How Tkinter Wraps Tcl/Tk了解Tkinter如何包装Tcl/Tk¶
When your application uses Tkinter’s classes and methods, internally Tkinter is assembling strings representing Tcl/Tk commands, and executing those commands in the Tcl interpreter attached to your applicaton’s 当应用程序使用Tkinter的类和方法时,Tkinter在内部组装表示Tcl/Tk命令的字符串,并在附加到应用程序Tk
instance.Tk
实例的Tcl解释器中执行这些命令。
Whether it’s trying to navigate reference documentation, trying to find the right method or option, adapting some existing code, or debugging your Tkinter application, there are times that it will be useful to understand what those underlying Tcl/Tk commands look like.无论是尝试浏览参考文档,尝试找到正确的方法或选项,修改一些现有代码,还是调试Tkinter应用程序,有时了解这些底层Tcl/Tk命令的样子都会很有用。
To illustrate, here is the Tcl/Tk equivalent of the main part of the Tkinter script above.为了举例说明,这里是与上述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’s syntax is similar to many shell languages, where the first word is the command to be executed, with arguments to that command following it, separated by spaces. Tcl的语法类似于许多shell语言,其中第一个单词是要执行的命令,后面是该命令的参数,用空格分隔。Without getting into too many details, notice the following:在不涉及太多细节的情况下,请注意以下几点:
The commands used to create widgets (like用于创建小部件(如ttk::frame
) correspond to widget classes in Tkinter.ttk::frame
)的命令对应于Tkinter中的小部件类。Tcl widget options (likeTcl小部件选项(如-text
) correspond to keyword arguments in Tkinter.-text
)对应于Tkinter中的关键字参数。Widgets are referred to by a pathname in Tcl (like小部件在Tcl中由pathname引用(如.frm.btn
), whereas Tkinter doesn’t use names but object references..frm.btn
),而Tkinter不使用名称,而是使用对象引用。A widget’s place in the widget hierarchy is encoded in its (hierarchical) pathname, which uses a小部件在小部件层次结构中的位置在其(层次)路径名中编码,该路径名使用.
(dot) as a path separator..
(点)作为路径分隔符。The pathname for the root window is just根窗口的路径名为.
(dot)..
(点)。In Tkinter, the hierarchy is defined not by pathname but by specifying the parent widget when creating each child widget.在Tkinter中,层次结构不是通过路径名定义的,而是通过在创建每个子小部件时指定父小部件来定义的。Operations which are implemented as separate commands in Tcl (like在Tcl中作为单独commands实现的操作(如grid
ordestroy
) are represented as methods on Tkinter widget objects.grid
或destroy
)表示为Tkinter小部件对象上的方法。As you’ll see shortly, at other times Tcl uses what appear to be method calls on widget objects, which more closely mirror what would is used in Tkinter.很快您就会看到,Tcl在其他时候会对小部件对象使用看似方法的调用,这更接近于Tkinter中使用的方法。
How do I…? What option does…?功能和选项¶
If you’re not sure how to do something in Tkinter, and you can’t immediately find it in the tutorial or reference documentation you’re using, there are a few strategies that can be helpful.如果您不确定如何在Tkinter中执行某些操作,并且您无法立即在所使用的教程或参考文档中找到它,那么有一些策略可能会有所帮助。
First, remember that the details of how individual widgets work may vary across different versions of both Tkinter and Tcl/Tk. 首先,请记住,Tkinter和Tcl/Tk的不同版本中,各个小部件的工作细节可能会有所不同。If you’re searching documentation, make sure it corresponds to the Python and Tcl/Tk versions installed on your system.如果要搜索文档,请确保它与系统上安装的Python和Tcl/Tk版本相对应。
When searching for how to use an API, it helps to know the exact name of the class, option, or method that you’re using. 在搜索如何使用API时,了解您正在使用的类、选项或方法的确切名称会有所帮助。Introspection, either in an interactive Python shell or with 在交互式Python shell或print()
, can help you identify what you need.print()
中进行内省可以帮助您确定所需内容。
To find out what configuration options are available on any widget, call its 要找出任何小部件上都有哪些配置选项,请调用其configure()
method, which returns a dictionary containing a variety of information about each object, including its default and current values. configure()
方法,该方法返回一个字典,其中包含关于每个对象的各种信息,包括其默认值和当前值。Use 使用keys()
to get just the names of each option.keys()
只获取每个选项的名称。
btn = ttk.Button(frm, ...)
print(btn.configure().keys())
As most widgets have many configuration options in common, it can be useful to find out which are specific to a particular widget class. 由于大多数小部件都有许多共同的配置选项,因此找出特定小部件类的特定配置选项可能很有用。Comparing the list of options to that of a simpler widget, like a frame, is one way to do that.将选项列表与更简单的小部件(如框架)的列表进行比较是一种方法。
print(set(btn.configure().keys()) - set(frm.configure().keys()))
Similarly, you can find the available methods for a widget object using the standard 类似地,您可以使用标准的dir()
function. dir()
函数找到小部件对象的可用方法。If you try it, you’ll see there are over 200 common widget methods, so again identifying those specific to a widget class is helpful.如果您尝试一下,您将看到有200多个常见的小部件方法,因此再次识别特定于小部件类的方法很有帮助。
print(dir(btn))
print(set(dir(btn)) - set(dir(frm)))
Threading model线程模型¶
Python and Tcl/Tk have very different threading models, which Python和Tcl/Tk有非常不同的线程模型,tkinter
tries to bridge. tkinter
试图将其桥接起来。If you use threads, you may need to be aware of this.如果使用线程,可能需要注意这一点。
A Python interpreter may have many threads associated with it. Python解释器可能有许多与之关联的线程。In Tcl, multiple threads can be created, but each thread has a separate Tcl interpreter instance associated with it. 在Tcl中,可以创建多个线程,但每个线程都有一个单独的与之关联的Tcl解释器实例。Threads can also create more than one interpreter instance, though each interpreter instance can be used only by the one thread that created it.线程还可以创建多个解释器实例,尽管每个解释器实例只能由创建它的一个线程使用。
Each Tk
object created by tkinter
contains a Tcl interpreter. Tk
创建的每个Tk
对象都包含一个Tcl解释器。It also keeps track of which thread created that interpreter. 它还跟踪哪个线程创建了该解释器。Calls to 可以从任何Python线程调用tkinter
can be made from any Python thread. tkinter
。Internally, if a call comes from a thread other than the one that created the 在内部,如果调用来自创建Tk
object, an event is posted to the interpreter’s event queue, and when executed, the result is returned to the calling Python thread.Tk
对象的线程以外的线程,则会将一个事件发布到解释器的事件队列,执行时,结果会返回给调用Python的线程。
Tcl/Tk applications are normally event-driven, meaning that after initialization, the interpreter runs an event loop (i.e. Tcl/Tk应用程序通常是事件驱动的,这意味着在初始化之后,解释器运行一个事件循环(即Tk.mainloop()
) and responds to events. Because it is single-threaded, event handlers must respond quickly, otherwise they will block other events from being processed. Tk.mainloop()
)并响应事件。因为它是单线程的,所以事件处理程序必须快速响应,否则它们将阻止处理其他事件。To avoid this, any long-running computations should not run in an event handler, but are either broken into smaller pieces using timers, or run in another thread. 为了避免这种情况,任何长时间运行的计算都不应该在事件处理程序中运行,而应该使用计时器将其分解成更小的部分,或者在另一个线程中运行。This is different from many GUI toolkits where the GUI runs in a completely separate thread from all application code including event handlers.这与许多GUI工具包不同,在这些工具包中,GUI在与所有应用程序代码(包括事件处理程序)完全独立的线程中运行。
If the Tcl interpreter is not running the event loop and processing events, any 如果Tcl解释器没有运行事件循环和处理事件,则从运行Tcl解释器的线程以外的线程进行的任何tkinter
calls made from threads other than the one running the Tcl interpreter will fail.tkinter
调用都将失败。
A number of special cases exist:存在一些特殊情况:
Tcl/Tk libraries can be built so they are not thread-aware.可以构建Tcl/Tk库,使它们不具有线程意识。In this case,在这种情况下,tkinter
calls the library from the originating Python thread, even if this is different than the thread that created the Tcl interpreter.tkinter
从原始Python线程调用库,即使这与创建Tcl解释器的线程不同。A global lock ensures only one call occurs at a time.全局锁确保一次只发生一个调用。
While虽然tkinter
allows you to create more than one instance of aTk
object (with its own interpreter), all interpreters that are part of the same thread share a common event queue, which gets ugly fast.tkinter
允许您创建一个Tk
对象的多个实例(使用它自己的解释器),但属于同一线程的所有解释器都共享一个公共事件队列,这很快就会发生。In practice, don’t create more than one instance of实际上,一次不要创建多个Tk
at a time.Tk
实例。Otherwise, it’s best to create them in separate threads and ensure you’re running a thread-aware Tcl/Tk build.否则,最好在单独的线程中创建它们,并确保您正在运行线程感知的Tcl/Tk构建。
Blocking event handlers are not the only way to prevent the Tcl interpreter from reentering the event loop.阻止事件处理程序并不是阻止Tcl解释器重新进入事件循环的唯一方法。It is even possible to run multiple nested event loops or abandon the event loop entirely.甚至可以运行多个嵌套事件循环或完全放弃事件循环。If you’re doing anything tricky when it comes to events or threads, be aware of these possibilities.如果您在处理事件或线程时遇到任何棘手的问题,请注意这些可能性。
There are a few select有几个selecttkinter
functions that presently work only when called from the thread that created the Tcl interpreter.tkinter
函数目前仅在从创建Tcl解释器的线程调用时工作。
Handy Reference方便的参考资料¶
Setting Options设置选项¶
Options control things like the color and border width of a widget. 选项控制控件的颜色和边框宽度等。Options can be set in three ways:可通过三种方式设置选项:
At object creation time, using keyword arguments在对象创建时,使用关键字参数-
fred = Button(self, fg="red", bg="blue")
After object creation, treating the option name like a dictionary index创建对象后,将选项名称视为字典索引-
fred["fg"] = "red"
fred["bg"] = "blue" Use the config() method to update multiple attrs subsequent to object creation使用config()
方法在创建对象之后更新多个属性-
fred.config(fg="red", bg="blue")
For a complete explanation of a given option and its behavior, see the Tk man pages for the widget in question.有关给定选项及其行为的完整解释,请参阅相关小部件的Tk手册页。
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.标准选项记录在options(3)手册页上。
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.command
选项,标签没有。
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. config()
方法,或者通过调用该小部件上的keys()
方法来查询。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.'relief'
),其值是5元组。
Some options, like 有些选项(如bg
are synonyms for common options with long names (bg
is shorthand for “background”). bg
)是具有长名称的常见选项的同义词(bg
是“背景”的缩写)。Passing the 通过config()
method the name of a shorthand option will return a 2-tuple, not 5-tuple. config()
方法传递速记选项的名称将返回2元组,而不是5元组。The 2-tuple passed back will contain the name of the synonym and the “real” option (such as 传回的2元组将包含同义词的名称和“real”选项(例如('bg', 'background')
).('bg', 'background')
)。
|
|
|
---|---|---|
0 |
|
|
1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
Example:例子:
>>> print(fred.config())
{'relief': ('relief', 'relief', 'Relief', 'raised', 'groove')}
Of course, the dictionary printed will include all the options available and their values. 当然,打印的字典将包括所有可用选项及其值。This is meant only as an example.这只是一个例子。
The Packer封隔器¶
The packer is one of Tk’s geometry-management mechanisms. 封隔器是Tk的几何管理机制之一。Geometry managers are used to specify the relative positioning of widgets within their container - their mutual master. 几何体管理器用于指定小部件在其容器中的相对位置,即它们的共同master。In contrast to the more cumbersome placer (which is used less commonly, and we do not cover here), the packer takes qualitative relationship specification - above, to the left of, filling, etc - and works everything out to determine the exact placement coordinates for you.与较笨重的placer(不太常用,此处不作介绍)相比,封隔器采用定性关系规范(above、to the left of、filling等),并解决所有问题,为您确定准确的放置坐标。
The size of any master widget is determined by the size of the “slave widgets” inside. 任何master窗口小部件的大小都由内部“从属窗口小部件”的大小决定。The packer is used to control where slave widgets appear inside the master into which they are packed. 打包器用于控制从窗口小部件在打包到的主窗口小部件中出现的位置。You can pack widgets into frames, and frames into other frames, in order to achieve the kind of layout you desire. 您可以将小部件打包到框架中,并将框架打包到其他框架中,以实现所需的布局类型。Additionally, the arrangement is dynamically adjusted to accommodate incremental changes to the configuration, once it is packed.此外,一旦包装完成,布局将动态调整,以适应配置的增量更改。
Note that widgets do not appear until they have had their geometry specified with a geometry manager. 请注意,小部件在使用几何体管理器指定其几何体之前不会显示。It’s a common early mistake to leave out the geometry specification, and then be surprised when the widget is created but nothing appears. 忽略几何体规范是早期常见的错误,当创建了小部件但什么都没有出现时,会感到惊讶。A widget will appear only after it has had, for example, the packer’s 小部件只有在应用了打包程序的pack()
method applied to it.pack()
方法后才会出现。
The pack() method can be called with keyword-option/value pairs that control where the widget is to appear within its container, and how it is to behave when the main application window is resized. pack()
方法可以使用关键字选项/值对调用,这些关键字选项/值对控制小部件在其容器中的显示位置,以及调整主应用程序窗口大小时的行为。Here are some examples:以下是一些示例:
fred.pack() # defaults to side = "top"
fred.pack(side="left")
fred.pack(expand=1)
Packer Options封隔器选项¶
For more extensive information on the packer and the options that it can take, see the man pages and page 183 of John Ousterhout’s book.有关封隔器及其选项的更多信息,请参阅约翰·欧斯特豪特(JohnOusterhout)书的手册页和第183页。
- anchor
Anchor type. Denotes where the packer is to place each slave in its parcel.锚类型。表示打包机将在包裹中放置每个从机的位置。- expand
Boolean,布尔值,0
or1
.0
或1
。- fill
Legal values:合法值:'x'
,'y'
,'both'
,'none'
.'x'
、'y'
、'both'
、'none'
。- ipadx and ipady
A distance - designating internal padding on each side of the slave widget.距离-指定从属小部件每侧的内部填充。- padx and pady
A distance - designating external padding on each side of the slave widget.距离-指定从窗口小部件每侧的外部填充。- side
Legal values are:合法值为:'left'
,'right'
,'top'
,'bottom'
.'left'
、'right'
、'top'
、'bottom'
。
Coupling Widget Variables耦合小部件变量¶
The current-value setting of some widgets (like text entry widgets) can be connected directly to application variables by using special options. 一些小部件(如文本输入小部件)的当前值设置可以通过使用特殊选项直接连接到应用程序变量。These options are 这些选项是variable
, textvariable
, onvalue
, offvalue
, and value
. variable
、textvariable
、onvalue
、offvalue
和value
。This connection works both ways: if the variable changes for any reason, the widget it’s connected to will be updated to reflect the new value.这种连接是双向的:如果变量因任何原因发生更改,它连接到的小部件将被更新以反映新值。
Unfortunately, in the current implementation of 不幸的是,在tkinter
it is not possible to hand over an arbitrary Python variable to a widget through a variable
or textvariable
option. tkinter
的当前实现中,不可能通过variable
或textvariable
选项将任意Python变量传递给小部件。The only kinds of variables for which this works are variables that are subclassed from a class called Variable, defined in 唯一适用的变量类型是从tkinter中定义的名为tkinter
.tkinter
的类中派生出来的变量。
There are many useful subclasses of Variable already defined: 已经定义了许多有用的变量子类:StringVar
, IntVar
, DoubleVar
, and BooleanVar
. StringVar
、IntVar
、DoubleVar
和BooleanVar
。To read the current value of such a variable, call the 要读取此类变量的当前值,请对其调用get()
method on it, and to change its value you call the set()
method. get()
方法,要更改其值,请调用set()
方法。If you follow this protocol, the widget will always track the value of the variable, with no further intervention on your part.如果遵循此协议,小部件将始终跟踪变量的值,而无需您进一步干预。
For example:例如:
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()
The Window Manager窗口管理器¶
In Tk, there is a utility command, 在Tk中,有一个实用程序命令wm
, for interacting with the window manager. wm
,用于与窗口管理器交互。Options to the wm
command allow you to control things like titles, placement, icon bitmaps, and the like. wm
命令的选项允许您控制标题、位置、图标位图等。In 在tkinter
, these commands have been implemented as methods on the Wm
class. tkinter
中,这些命令已作为Wm
类上的方法实现。Toplevel widgets are subclassed from the Toplevel小部件是Wm
class, and so can call the Wm
methods directly.Wm
类的子类,因此可以直接调用Wm
方法。
To get at the toplevel window that contains a given widget, you can often just refer to the widget’s master. 要访问包含给定小部件的顶级窗口,通常只需参考小部件的主窗口即可。Of course if the widget has been packed inside of a frame, the master won’t represent a toplevel window. 当然,如果小部件已经打包在一个框架内,那么主窗口将不会表示顶级窗口。To get at the toplevel window that contains an arbitrary widget, you can call the 要获取包含任意小部件的顶级窗口,可以调用_root()
method. _root()
方法。This method begins with an underscore to denote the fact that this function is part of the implementation, and not an interface to Tk functionality.此方法以下划线开头,表示此函数是实现的一部分,而不是Tk功能的接口。
Here are some examples of typical usage:以下是一些典型用法的示例:
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 Option Data TypesTk选项数据类型¶
- anchor
Legal values are points of the compass:法律价值是Compass的指向:"n"
,"ne"
,"e"
,"se"
,"s"
,"sw"
,"w"
,"nw"
, and also"center"
."n"
、"ne"
、"e"
、"se"
、"s"
、"sw"
、"w"
、"nw"
和"center"
。- bitmap
There are eight built-in, named bitmaps:有八个内置的名为位图:'error'
,'gray25'
,'gray50'
,'hourglass'
,'info'
,'questhead'
,'question'
,'warning'
.'error'
、'gray25'
、'gray50'
、'hourglass'
、'info'
、'questhead'
、'question'
、'warning'
。To specify an X bitmap filename, give the full path to the file, preceded with an要指定X位图文件名,请提供文件的完整路径,前面加@
, as in"@/usr/contrib/bitmap/gumby.bit"
.@
,如"@/usr/contrib/bitmap/gumby.bit"
所示。- boolean
You can pass integers 0 or 1 or the strings您可以传递整数0或1或字符串"yes"
or"no"
."yes"
或"no"
。- callback
This is any Python function that takes no arguments.这是任何不带参数的Python函数。For example:例如:def print_it():
print("hi there")
fred["command"] = print_it- color
Colors can be given as the names of X colors in the rgb.txt file, or as strings representing RGB values in 4 bit:颜色可以在rgb.txt文件中以X颜色的名称给出,也可以以4位:"#RGB"
, 8 bit:"#RRGGBB"
, 12 bit:"#RRRGGGBBB"
, or 16 bit:"#RRRRGGGGBBBB"
ranges, where R,G,B here represent any legal hex digit."#RGB"
、8位:"#RRGGBB"
、12位:"#RRRGGGBBB"
或16位:"#RRRRGGGGBBBB"
范围中表示RGB值的字符串给出,其中R、G、B在此表示任何合法的十六进制数字。See page 160 of Ousterhout’s book for details.详情参见Ousterhout的书第160页。- cursor
The standard X cursor names from可以使用cursorfont.h
can be used, without theXC_
prefix.cursorfont.h
中的标准X光标名称,无需XC_
前缀。For example to get a hand cursor (例如,要获取指针(XC_hand2
), use the string"hand2"
.XC_hand2
),请使用字符串"hand2"
。You can also specify a bitmap and mask file of your own.您还可以指定自己的位图和掩码文件。See page 179 of Ousterhout’s book.请参阅Ousterhout的书第179页。- distance
Screen distances can be specified in either pixels or absolute distances.屏幕距离可以用像素或绝对距离指定。Pixels are given as numbers and absolute distances as strings, with the trailing character denoting units:像素以数字表示,绝对距离以字符串表示,尾随字符表示单位:c
for centimetres,i
for inches,m
for millimetres,p
for printer’s points.c
表示厘米,i
表示英寸,m
表示毫米,p
表示打印机点。For example, 3.5 inches is expressed as例如,3.5英寸表示为"3.5i"
."3.5i"
。- font
Tk uses a list font name format, such asTk使用列表字体名称格式,如{courier 10 bold}
.{courier 10 bold}
。Font sizes with positive numbers are measured in points; sizes with negative numbers are measured in pixels.正数字体大小以点为单位;负数大小以像素为单位。- geometry
This is a string of the form这是一个格式为widthxheight
, where width and height are measured in pixels for most widgets (in characters for widgets displaying text).widthxheight
的字符串,其中大多数小部件的宽度和高度是以像素为单位测量的(对于显示文本的小部件,以字符为单位)。For example:例如:fred["geometry"] = "200x100"
.fred["geometry"] = "200x100"
。- justify
Legal values are the strings:合法值是字符串:"left"
,"center"
,"right"
, and"fill"
."left"
、"center"
、"right"
和"fill"
。- region
This is a string with four space-delimited elements, each of which is a legal distance (see above).这是一个由四个空格分隔的元素组成的字符串,每个元素都是合法距离(见上文)。For example:例如:"2 3 4 5"
and"3i 2i 4.5i 2i"
and"3c 2c 4c 10.43c"
are all legal regions."2 3 4 5"
和"3i 2i 4.5i 2i"
以及“3c 2c 4c 10.43c”都是法律区域。- relief
Determines what the border style of a widget will be.确定小部件的边框样式。Legal values are:合法值为:"raised"
,"sunken"
,"flat"
,"groove"
, and"ridge"
."raised"
、"sunken"
、"flat"
、"groove"
和"ridge"
。- scrollcommand
This is almost always the这几乎总是一些滚动条小部件的set()
method of some scrollbar widget, but can be any widget method that takes a single argument.set()
方法,但可以是任何接受单个参数的小部件方法。- wrap
Must be one of:必须是"none"
,"char"
, or"word"
."none"
、"char"
或"word"
之一。
Bindings and Events绑定和事件¶
The bind method from the widget command allows you to watch for certain events and to have a callback function trigger when that event type occurs. widget命令中的bind方法允许您监视某些事件,并在该事件类型发生时具有回调函数触发器。The form of the bind method is:bind方法的形式为:
def bind(self, sequence, func, add=''):
where:其中:
- sequence
is a string that denotes the target kind of event.是一个字符串,表示事件的目标类型。(See the bind man page and page 201 of John Ousterhout’s book for details).(有关详细信息,请参阅约翰·奥斯特豪特的书中的装订手册页和201页)。- func
is a Python function, taking one argument, to be invoked when the event occurs.是一个Python函数,带有一个参数,将在事件发生时调用。An Event instance will be passed as the argument.事件实例将作为参数传递。(Functions deployed this way are commonly known as callbacks.)(以这种方式部署的函数通常称为callbacks。)- add
is optional, either''
or'+'
.''
或'+'
,是可选的。Passing an empty string denotes that this binding is to replace any other bindings that this event is associated with.传递空字符串表示此绑定将替换与此事件关联的任何其他绑定。Passing a传递'+'
means that this function is to be added to the list of functions bound to this event type.'+'
表示将此函数添加到绑定到此事件类型的函数列表中。
For example:例如:
def turn_red(self, event):
event.widget["activeforeground"] = "red"
self.button.bind("<Enter>", self.turn_red)
Notice how the widget field of the event is being accessed in the 注意如何在turn_red()
callback. turn_red()
回调中访问事件的小部件字段。This field contains the widget that caught the X event. 此字段包含捕获X事件的小部件。The following table lists the other event fields you can access, and how they are denoted in Tk, which can be useful when referring to the Tk man pages.下表列出了您可以访问的其他事件字段,以及它们在Tk中的表示方式,这在引用Tk手册页时非常有用。
Tk |
|
Tk |
|
---|---|---|---|
%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 |
The index Parameter索引参数¶
A number of widgets require “index” parameters to be passed. 许多小部件需要传递“索引”参数。These are used to point at a specific place in a Text widget, or to particular characters in an Entry widget, or to particular menu items in a Menu widget.它们用于指向文本小部件中的特定位置,或指向条目小部件中的特定字符,或指向菜单小部件中的特定菜单项。
Entry widget indexes (index, view index, etc.)条目小部件索引(索引、视图索引等)Entry widgets have options that refer to character positions in the text being displayed.输入窗口小部件具有指向所显示文本中字符位置的选项。You can use these您可以使用这些tkinter
functions to access these special points in text widgets:tkinter
函数访问文本小部件中的这些特殊点:Text widget indexes文本小部件索引The index notation for Text widgets is very rich and is best described in the Tk man pages.文本小部件的索引符号非常丰富,最好在Tk手册页中进行描述。Menu indexes (menu.invoke(), menu.entryconfig(), etc.)菜单索引(menuinvoke()
、menuentryconfig()
等)Some options and methods for menus manipulate specific menu entries.菜单的某些选项和方法操作特定的菜单项。Anytime a menu index is needed for an option or a parameter, you may pass in:任何时候需要选项或参数的菜单索引,您都可以传入:an integer which refers to the numeric position of the entry in the widget, counted from the top, starting with 0;一个整数,表示小部件中条目的数字位置,从顶部开始计算,从0开始;the string字符串"active"
, which refers to the menu position that is currently under the cursor;"active"
,表示当前光标下的菜单位置;the string字符串"last"
which refers to the last menu item;"last"
,表示最后一个菜单项;An integer preceded by前跟@
, as in@6
, where the integer is interpreted as a y pixel coordinate in the menu’s coordinate system;@
,如@6
,其中整数被解释为菜单坐标系中的y像素坐标;the string字符串"none"
, which indicates no menu entry at all, most often used with menu.activate() to deactivate all entries, and finally,"none"
表示根本没有菜单项,最常用于menuactivate()
来停用所有项,最后,a text string that is pattern matched against the label of the menu entry, as scanned from the top of the menu to the bottom.从菜单顶部到底部扫描时,与菜单项标签模式匹配的文本字符串。Note that this index type is considered after all the others, which means that matches for menu items labelled请注意,此索引类型是在所有其他索引类型之后考虑的,这意味着标记为last
,active
, ornone
may be interpreted as the above literals, instead.last
、active
或none
的菜单项的匹配可能会被解释为上述文本。
Images¶
Images of different formats can be created through the corresponding subclass of 可以通过tkinter.Image
:tkinter.Image
的相应子类创建不同格式的图像:
BitmapImage
for images in XBM format.用于XBM格式的图像。PhotoImage
for images in PGM, PPM, GIF and PNG formats.用于PGM、PPM、GIF和PNG格式的图像。The latter is supported starting with Tk 8.6.从Tk 8.6开始支持后者。
Either type of image is created through either the 这两种类型的图像都是通过file
or the data
option (other options are available as well).file
或data
选项创建的(也可以使用其他选项)。
The image object can then be used wherever an 然后,可以在某些小部件(例如标签、按钮、菜单)支持image
option is supported by some widget (e.g. labels, buttons, menus). image
选项的任何位置使用图像对象。In these cases, Tk will not keep a reference to the image. 在这些情况下,Tk不会保留对图像的引用。When the last Python reference to the image object is deleted, the image data is deleted as well, and Tk will display an empty box wherever the image was used.当删除对图像对象的最后一个Python引用时,图像数据也会被删除,并且无论在哪里使用图像,Tk都会显示一个空框。
File Handlers文件处理程序¶
Tk allows you to register and unregister a callback function which will be called from the Tk mainloop when I/O is possible on a file descriptor. Tk允许您注册和注销回调函数,当可以对文件描述符进行I/O时,将从Tk mainloop调用回调函数。Only one handler may be registered per file descriptor. 每个文件描述符只能注册一个处理程序。Example code:示例代码:
import tkinter
widget = tkinter.Tk()
mask = tkinter.READABLE | tkinter.WRITABLE
widget.tk.createfilehandler(file, mask, callback)
...
widget.tk.deletefilehandler(file)
This feature is not available on Windows.此功能在Windows上不可用。
Since you don’t know how many bytes are available for reading, you may not want to use the 由于您不知道有多少字节可供读取,因此可能不想使用BufferedIOBase
or TextIOBase
read()
or readline()
methods, since these will insist on reading a predefined number of bytes. BufferedIOBase
或TextIOBase
read()
或readline()
方法,因为这些方法将坚持读取预定义的字节数。For sockets, the 对于套接字,recv()
or recvfrom()
methods will work fine; for other files, use raw reads or os.read(file.fileno(), maxbytecount)
.recv()
或recvfrom()
方法可以正常工作;对于其他文件,请使用原始读取或os.read(file.fileno(), maxbytecount)
。
-
Widget.tk.
createfilehandler
(file, mask, func)¶ Registers the file handler callback function func.注册文件处理程序回调函数func。The file argument may either be an object with afile参数可以是具有fileno()
method (such as a file or socket object), or an integer file descriptor.fileno()
方法的对象(例如文件或套接字对象),也可以是整数文件描述符。The mask argument is an ORed combination of any of the three constants below.mask参数是以下三个常量中任意一个的OR组合。The callback is called as follows:回调调用如下:callback(file, mask)
-
Widget.tk.
deletefilehandler
(file)¶ Unregisters a file handler.注销文件处理程序。