3 tkinter 基础概念

参考资源:

  • TKDocs:大量的教程,部分可视化组件的介绍说明

Python3.7 已经自动集成了 tkinter,无需安装。

Tk 程序有 3 个基础概念:部件(widgets)、几何管理(geometry management)、事件处理(event handling)。下面逐一介绍。

1 Widgets

widgets (有时也称为 controls(控件)或者 windows(窗口))指代您在屏幕上看到的对象,包含有 button,entry,labels,frame,checkboxes,tree views,scrollbars,text areas 等等。

1.1 窗口具有层次结构

在 Tk 中所有的 widgets 都是一个单根(root,即最顶层的 widget)的具有层次结构的窗口(Window Hierarchy)。当我们创建一个 widget 时必须传入它的父节点。比如:

from tkinter import ttk
from tkinter import Tk
root = Tk() # 实例化顶层 widget
content = ttk.Frame(root)
button = ttk.Button(content)

可以使用 str(widget) 获取该 widget 的层级结构(有点类似于文件的路径):

str(root), str(content), str(button)

显示结果为:

('.', '.!frame', '.!frame.!button')

可以看出 root 是最顶层的,其次是 content,最后是 button。

1.2 配置选项

所有的 widgets 均有一些配置选项(configuration options),这些选项控制着 widgets 的行为(即如何表现事件的)和状态(即如何被展示的)。下面举例说明:

root = Tk() # 创建顶层 widget
# 向一个 button 传入两个配置选项
button = ttk.Button(root, text='您好', command='buttonpressed')

可以直接使用索引的方式获取配置信息:

button['text']

显示结果为:

'您好'

也可以修改配置信息:

button['text'] = '再见'     # 等价于 button.configure(text='再见')

如果需要获取 'text' 的配置信息,可以:

button.configure('text')
('text', 'text', 'Text', '', '再见')

如果需要获取全部的配置信息,可以运行 button.configure() 命令。一些常用的 widgets:frames, labels, buttons, checkbuttons, radiobuttons, entries and comboboxes。您也可以使用 dict(button) 获取 button 的所有属性信息。即:

{'command': 'buttonpressed',
 'default': <index object: 'normal'>,
 'takefocus': 'ttk::takefocus',
 'text': '再见',
 'textvariable': '',
 'underline': -1,
 'width': '',
 'image': '',
 'compound': <index object: 'none'>,
 'padding': '',
 'state': <index object: 'normal'>,
 'cursor': '',
 'style': '',
 'class': ''}

2 Geometry Management

创建了 widgets 并不能让其直接在屏幕上显示,这是因为还缺少一个关键的步骤:Geometry Management(几何管理)。最常用的就是 grid 几何管理器。

几何管理器依赖于主部件和从部件(master and slave widgets)的概念设定。母版(master)是一个小部件,它通常是顶层窗口(toplevel window)或框架(frame),其中包含了其他小部件,这些小部件被称为从属项(slaves)。您可以将几何管理器当作是在主部件的控制下,决定着在窗口显示着些什么内容。

几何管理器将会询问每个从属部件的自然大小,或者它理想情况下希望显示的大小。然后,当它要求几何管理器管理该特定的从属部件时,它会获取其信息并将其与程序提供的任何参数相结合。

几何管理器获取有关从属的所有信息,以及有关主部件大小的信息,并使用其内部算法确定每个从属部件将分配的区域。每当主参数的大小发生变化(例如,因为顶层窗口被调整大小)、从属窗口的自然大小变化(例如,因为我们已经更改了标签中的文本)或任何几何管理器参数更改(例如,如"row",,"column",或者 "sticky")。

3 Event Handling

在 Tk 中,与大多数其他用户界面工具包一样,有一个事件循环(event loop),从操作系统接收事件。这些事件有按钮按下、击键、鼠标移动、窗口调整大小等。

通常,Tk 会负责为您管理这些事件循环。它将找出事件应用于哪个小部件(用户是否单击此按钮?如果按下了某个键,哪个文本框具有焦点?),并相应地调度它。单个小部件知道如何响应事件;例如,当鼠标移动时,按钮可能会更改颜色,并在鼠标离开时恢复。

3.1 命令回调(Command Callbacks)

通常,尽管您希望程序处理特定事件,例如按下按钮时执行某些操作。对于自定义非常必要的事件(按下按钮时不发生某些内容,该按钮有什么好?),小部件将提供一个回调作为小部件配置选项(widget configuration option)。比如配置选项的 "command" 参数。

Tk 中的回调往往比用于编译语言的工具包中简单(其中回调通常必须针对具有特定参数集的过程或具有特定签名的对象方法)。相反,回调只是解释器执行的正常代码。

3.2 事件绑定

对于没有与其关联的命令回调的事件,可以使用 Tk 的 "bind" 捕获任何事件,然后(与回调类似)执行任意代码段。下面看一个简单的例子,它显示了标签如何设置绑定以响应不同的事件,而只需更改标签中显示的内容即可:

root = Tk()
l = ttk.Label(root, text="Starting...")
l.grid()
l.bind('<Enter>', lambda e: l.configure(text='Moved mouse inside'))
l.bind('<Leave>', lambda e: l.configure(text='Moved mouse outside'))
l.bind('<1>', lambda e: l.configure(text='Clicked left mouse button'))
l.bind('<Double-1>', lambda e: l.configure(text='Double clicked'))
l.bind('<B3-Motion>', lambda e: l.configure(text='right button drag to %d,%d' % (e.x, e.y)))
root.mainloop()

tkinter 希望您将函数作为事件回调,其第一个参数是表示触发回调的事件的事件对象(格式为 <modifier-type-detail>)。

  • type:是 event 的核心,通常用于描述事件的类型,比如点击鼠标
  • modifier:event 的可选部分,通常用于描述事件的组合键,例如 Ctrl + S
  • detail:event 的可选部分,通常用于描述事件的具体按键,例如 Button-3 表示鼠标右键

下面简单介绍几个事件:

事件 描述
<Button-1> 鼠标事件,1 代表左键,可简写为 <1>
<Button-2> 鼠标事件,2 代表中键,可简写为 <2>
<Button-3> 鼠标事件,3 代表右键,可简写为 <3>
<Button-4> 鼠标事件,4 代表鼠标滚轮上滚
<Button-5> 鼠标事件,5 代表鼠标滚轮下滚
<B1-Motion> 鼠标拖动事件,1 代表左键拖动,还有 2, 3 分别代表中键拖动,右键拖动
<ButtonRelease-1> 鼠标按下后释放
<Double-Button-1> 双击鼠标左键
<Enter> 表示鼠标指针进入到 widget 里面
<Leave> 表示鼠标指针离开 widget
<KeyPress-D> 用户点击按键 D
<Control-Shift-KeyPress-Y> 用户点击组合键 Ctrl + Shift + Y

事件对象的属性:

属性 描述
widget 产生的事件的组件
x, y 当前的鼠标相对于窗口的位置,单位:像素
x_root, y_root 当前的鼠标相对于电脑显示屏左上角的位置,单位:像素
char 仅键盘事件支持,表示按键对应的字符
num 按钮数字,仅支持鼠标事件
width, height widget 的大小
type 事件类型

对于所有不同的事件名称、修饰符和每个事件参数的完整描述,最好查看的是"绑定"命令引用

bind 还有两个变体:

  1. bind_all:参数同 bind,作用是绑定到全局
  2. bind_class:有 3 个参数,即 (类名, 事件类型, 对应的操作),比如:
    app.bind_class('ttk.Entry', '<Control-C>', my_copy) 绑定了所有的输入文本框的 Ctrl + C 表示复制

3.3 虚拟事件

除了低级操作系统事件(如鼠标单击和窗口调整大小)之外,许多小部件还生成称为虚拟事件(Virtual Events)的更高级别事件。例如,列表框小部件("ListboxSelect")将在选择更改时生成虚拟事件,无论这是因为用户单击了某个项目,还是使用箭头键移动到它等等。这样可以避免设置多个(可能是特定平台的事件绑定)来捕获更改的问题。

3.4 多重绑定

实际上,小部件可以针对单个事件触发(trigger)多个不同的事件绑定。通常,可以为以下设置事件:单个小部件本身、特定类的所有小部件(例如按钮)、包含小部件的顶级窗口以及应用程序中的所有小部件。每一个将依次触发。

当我们在顶层窗口中为 Return 键设置绑定时,我们在示例中看到了这一点,该绑定应用于该窗口中的每个小部件。

Tk 中每个小部件类的默认行为本身是使用脚本级事件绑定定义的,因此可以进行内省和修改,以更改特定类的所有小部件的行为。您甚至可以完全修改每个小部件的多个事件序列的处理;如果您好奇,请参阅"绑定标记"命令引用

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,904评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,581评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,527评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,463评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,546评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,572评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,582评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,330评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,776评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,087评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,257评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,923评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,571评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,192评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,436评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,145评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352