19.2 Tkinter与Python编程

19.2.1 Tkinter模块:把Tk引入你的程序

为了让Tkinter成为你程序的一部分,应该怎么做呢?这并不是说你一定要先有一个应用程序。只要你愿意,当然可以创建一个纯粹的GUI程序,但如果没有让人感兴趣的功能的话,这个程序也许不会很有用。

要创建并运行你的GUI程序,下面五步是基本的。

1.导入Tkinter模块(import Tkinter或者from Tkinter import*)。

2.创建一个顶层窗口对象,来容纳你的整个GUI程序。

3.在你的顶层窗口对象上(或者说在“其中”)创建所有的GUI模块(以及功能)。

4.把这些GUI模块与底层程序代码相连接。

5.进入主事件循环。

第一步很明显:所有使用Tkinter的GUI程序必须先导入Tkinter模块。第一步就是为了获得Tkinter的访问权(参见19.1.1小节)。

19.2.2 GUI程序开发简介

在举例之前,我们将先从宏观上来给你简单介绍一下GUI程序开发。这将给你以后的学习提供一些必要的背景知识。

创建GUI程序与画家作画有些相似。通常画家只会在一块画布上开展自己的创作。工作步骤或许是这样的:首先要找来一块干净的石板,你将在这个“顶层”窗口对象上创建所有其他模块。可以把这一步想象成一座房屋的地基或者某个画家的画架。换言之,在搭建各实物或展开画布之前,你必须先给地基浇灌好混凝土或者架好画架。对Tkinter而言,这个基础被称为顶层窗口对象。

在GUI程序中,会有一个顶层根窗口对象,它包含着所有小窗口对象,它们共同组成一个完整的GUI程序。这些小窗口对象可以是文字标签、按钮、列表框等等。这些独立的GUI构件就是所谓的组件。所以当我们说创建一个顶层窗口的时候,我们实际上是指你需要一个放置所有组件的地方。典型的Python语句如下行:

19.2 Tkinter与Python编程 - 图1

Tkinter. Tk()返回的对象通常被称作根窗口,正因为如此,有些程序用root来指示它,而非top。顶层窗口是指那些在你的程序中独立显示的部分。你可以在GUI程序中创建多个顶层窗口,但它们中只能有一个是根窗口。你可以采用先完全设计好组件再添加实际功能的开发方式,也可以二者同时进行。(这意味着交替执行上述5步中的第3步和第4步。)

组件既可以是独立的也可以作为容器存在。如果一个组件“包含”其他组件,它就被认为是这些组件的父组件。相应地,如果一个组件被“包含”在其他组件中,它就被认为是父组件的孩子,父组件则是直接包围其外的那个容器组件。

通常,组件会有一些相应的行为,例如按钮被按下,或者文本框被写入。这种形式的用户行为被称为事件,而GUI程序对事件所采取的响应动作被称为回调。

用户操作包括按下(以及释放)按钮、移动鼠标、按下RETURN或Enter键等等,所有的这些从系统角度都被看作事件。GUI程序正是由这伴随其始末的整套事件体系所驱动的。这个过程被称作事件驱动处理。

一个事件及其回调的例子是鼠标移动。我们假设鼠标指针停在你GUI程序的某处。如果鼠标被移到了程序的别处,一定是有什么东西引起了屏幕上指针的移动,从而表现这种位置的转移。系统必须处理这些鼠标移动事件才能展现(并实现)鼠标在窗口上的移动。一旦你释放了鼠标,就不再会有事件需要处理,相应地,屏幕上的一切又复归平静。

GUI程序的事件驱动特性恰好体现出它的客户端/服务器架构。当你启动一个GUI程序时,它必须执行一些初始化例程来为核心功能的运行做准备,正如启动一个网络服务器时必须先申请一个套接字并把它绑定在一个本地地址上一样。Tk有两个坐标管理器用来协助把组件放在正确的位置上;你将经常用到的一个称为“包”,亦即packer。另一个坐标管理器是网格(Grid)。你可以用它来把GUI组件放在网格坐标系中,Grid将依据GUI中的网格坐标来生成每个对象。我们将紧扣packer讲解。

一旦packer决定好你所有组件的尺寸和对齐方式,它将为你在屏幕上放置它们。当所有这些组件,包括顶层窗口,最终显示在你屏幕上时,GUI程序就会进入一个“服务器式”的无限循环。这个无限循环包括等待GUI事件、处理事件、然后返回等待模式,等待下一个事件。

上述最后一步说明所有组件就绪后立即进入主循环。这正是我们提及的“服务器式”无限循环。对Tkinter而言,相应代码如下:

19.2 Tkinter与Python编程 - 图2

这通常是你程序执行的最后一段代码。一旦进入主循环,GUI便从此掌握控制权。所有其他动作都来自回调函数,包括程序退出。当你拉下文件菜单点击“退出”菜单项或直接关闭窗口时,必须要唤起一个回调来结束你的程序。

19.2.3 顶层窗口:Tkinter.Tk()

我们前面提到所有的主要组件都建立在顶层窗口对象内。这个对象是由Tkinter中的Tk类创建的,并且是由普通构造器创建的:

19.2 Tkinter与Python编程 - 图3

在这个窗口中,你可以放置独立组件或集成的模块来构建你的GUI。那么,都有哪些组件可用呢?我们下面就来介绍Tk组件。

19.2.4 Tk组件

Tk目前有15种组件。我们在表19.1中列出了它们。

我们不准备对所有Tk组件都一一详细讲解,因为已经有许多关于它们的很好的文章可供参考——不论是从Python网站的Tkinter主题页面还是数量可观的Tcl/Tk印刷品,抑或是在线资源(其中一些可以在附录B中找到)。然而,我们将讲解一些例子来帮你启航。

19.2 Tkinter与Python编程 - 图4

19.2 Tkinter与Python编程 - 图5核心笔记:默认参数是你的朋友

GUI开发从Python的缺省参数机制获益匪浅,因为Tkinter组件有大量的默认动作。除非你熟知自己使用的每一个组件的每一个可用选项,否则最好只设置你关心的参数而把其他的交由系统处理。这些缺省值是精心选出的。

如果你没有提供这些值也不必担心程序会在屏幕上表现怪异。作为一条基本规则,程序都由一系列经优化的缺省值创建,并且只有当你明确知道如何配置你的组件时,才有必要用自己的值替换这些缺省值。

例19.1

我们的第一个Tkinter例子是……还能是什么呢?“Hello World!”具体地说,是介绍我们的第一个组件:标签。

19.2 Tkinter与Python编程 - 图6