第一个真正的 GUI 程序——Tkinter教程系列02

前言

欢迎光临我的个人博客 chens.life

Tk 系列教程:

我们将编写一个英尺和米的转换程序,通过这个程序,我们将会了解一个真正的实用程序该怎么设计和编写,我们也将会了解到 Tk 程序内部的基本样子。不必完全掌握里面的所有知识,更多细节将会在之后的章节中讲到。本节仅要求了解即可,使读者明白如何设计和编写一个 Tk GUI 程序。

设计

我们将要写一个简单的将英尺(feet)转换为米(meters)的 GUI 工具,按照我们的经验,它应该长成下面那个样子(图1):

这个程序会有一个输入框用来输入英尺数,还将会有一个显示框用来显示被转换之后的数字,几个用于显示提示字符的文本区域,同样重要的是,必须有一个转换触发按钮。

不难发现,这个程序大致被分为了三行三列,这很重要,关乎之后的 几何管理(用于控制组件的大小和位置),我们将在之后章节中讲到。

代码

from tkinter import *
from tkinter import ttk def calculate(*args):
try:
value = float(feet.get())
meters.set((0.3048 * value * 10000.0 + 0.5)/10000.0)
except ValueError:
pass root = Tk()
root.title("Feet to Meters")
mainframe = ttk.Frame(root, padding="3 3 15 15")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1) feet = StringVar()
meters = StringVar() feet_entry = ttk.Entry(mainframe, width=7, textvariable=feet)
feet_entry.grid(column=2, row=1, sticky=(W, E)) ttk.Label(mainframe, textvariable=meters).grid(column=2, row=2, sticky=(W, E))
ttk.Button(mainframe, text="转换", command=calculate).grid(column=3, row=3, sticky=W) ttk.Label(mainframe, text="英尺").grid(column=3, row=1, sticky=W)
ttk.Label(mainframe, text="等于").grid(column=1, row=2, sticky=E)
ttk.Label(mainframe, text="米").grid(column=3, row=2, sticky=W) for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5) feet_entry.focus()
root.bind('<Return>', calculate) root.mainloop()

最终会是这个样子(图二):

逐步解释

我们要编写 Tk 程序,首先要引入 Tkinter 的模块。

from tkinter import *
from tkinter import ttk

这两行告诉 Python 我们的程序需要这两个模块。首先,tkinter 是 Tk 的标准包,当它加载的时候,也会导致 Tk 函数库在你的系统中被加载。其次,ttk 是 在Tk 8.5 中新添加的,提供对 Tk 8.5 中引入的Tk主题小部件集的访问,其基本思想是将实现小部件行为的代码与实现其外观的代码尽可能地分开,在这里我们不去深究。

值得注意的是,我们已经从 tkinter 模块中导入了所有函数,因此我们可以直接调用 tkinter 的所有函数而不需要添加前缀。但是我们只导入了 ttk 模块,所以在使用 ttk 模块中的函数时应该增加 ttk 前缀。

如果你要将旧代码修改为新代码,你会发现 Tkinter 的名字从大写变成了小写 tkinter,这个改变从 Python 3.0 开始。

root = Tk()
root.title("Feet to Meters")
mainframe = ttk.Frame(root, padding="3 3 15 15")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)

calculate函数将会在后面讲解,之所以放到前面,是因为后面的许多语句需要调用它。

root = Tk() 语句构建了一个main窗口,也被称为root窗口。使用 root.title("title") 为窗口赋予一个名字。ttk.Frame(root, padding="3 3 15 15") 建立一个框架,这个框架分为三行三列,像素为15。我们将这个框架放置到到root窗口中,不同的是,我们的所有组件都被放到了这个框架中而不是root窗口。

一般来说,我们可以将所有的组件(Widget)都放到 root 窗口中,但是主窗口的背景可能与我们添加的组件不匹配,这时候,我们添加一个中间框架(Frame),将组件放到这个中间框架上来保证内容与背景的匹配。

columncoonfigure和 rowconfigure 告诉 Tk, 当主窗口重新改变了大小,那么在这之上的 Frame 框架也应该变化,以占用多余的空间。

feet = StringVar()
meters = StringVar()
feet_entry = ttk.Entry(mainframe, width=7, textvariable=feet)
feet_entry.grid(column=2, row=1, sticky=(W, E)) ttk.Label(mainframe, textvariable=meters).grid(column=2, row=2, sticky=(W, E))
ttk.Button(mainframe, text="转换", command=calculate).grid(column=3, row=3, sticky=W)

上面的几条语句在框架上(mainframe)创建了三个组件,输入框、输出区域(Label,用于放置转换的结果)、转换按钮。

对于每一个组件(Widget),我们需要做两件事:

  1. 创建
  2. 放置

他们都是 ttk 模块中的类。创建时,我们指定传入的参数:放置的框架,大小,按钮中的字符等。至于 textvariable 的意思,它指这个输入框或者输出框中的值所关联的变量,而这个变量的类型是 StringVar 的对象。

我们使用 grid(网格) 进行几何管理,意思就是这个组件将放在哪一个地方(哪一行,哪一列),sticky 指明组件在分配给它的网格单元(grid cell)中的排列(line up)方式,E、W、S、N就是东西南北的意思,类似于文本编辑器中的 居中、靠左、靠右等。

ttk.Label(mainframe, text="英尺").grid(column=3, row=1, sticky=W)
ttk.Label(mainframe, text="等于").grid(column=1, row=2, sticky=E)
ttk.Label(mainframe, text="米").grid(column=3, row=2, sticky=W)

上述三行创建了三个指定内容的 文本标签(Label),并放到了指定的位置。

for child in mainframe.winfo_children():
child.grid_configure(padx=5, pady=5)
feet_entry.focus()
root.bind('<Return>', calculate)

这四行代码为我们的图形化做了一个漂亮的收尾工作。

前两行代码遍历所有的放置在 mainframe 中的组件,并在它们周围增加了一些边框,使它们不至于都挤在一起。当然也可以单独遍历这些组件,然后逐个进行设置,但这不是方便的做法。

第三行代码告诉 Tk,在程序运行时,将光标聚焦在输入框中,使用户不必再点击一下输入框。

第四行代码告诉 Tk,当用户在按下 Return(Windows 中是 Enter)时,调用 calculate 函数。这与按下按钮调用 calculate 函数是一样的。

def calculate(*args):
try:
value = float(feet.get())
meters.set((0.3048 * value * 10000.0 + 0.5)/10000.0)
except ValueError:
pass

这里我们定义了一个 calculate 函数调用,当按下 Return、Enter(Windows),或者转换按钮时它将会被调用。它从输入框中获取用户输入的数值,然后将其转换为单位为米的数值之后,将输入框中的数值设置为正确的结果。

显然看到,calculate 函数通过获取 feet和设置 meters来改变在它们各自对应的输入框(Entry)和输出框(Label)中的数值显示。当用户的输入改变时,对应的feet的值就会被修改为对应的输入值;当meters被被修改时,对应的输出框(Label)显示的值也会改变。这就是在定义 feet_entry(输入框)和 label(输出框)时,还要指定 textvariable的值的原因,而它的值应该是一个 StringVar的对象。如以下示例:

feet = StringVar()
meters = StringVar()
feet_entry = ttk.Entry(mainframe, width=7, textvariable=feet)
ttk.Label(mainframe, textvariable=meters).grid(column=2, row=2, sticky=(W, E))
root.mainloop()

最后一句告诉 Tk 进入事件循环(event loop),这是使一些运行起来所必须的。

后记

未完待续。。。欢迎持续关注。

下一章节我们将会讲解 Tk 中的几何管理,它是将多种组件合理的进行组织和摆放的关键,我们这节使用的 grid 就是其中的一种。当然,它也是一个难点。

第一个真正的 GUI 程序——Tkinter教程系列02的更多相关文章

  1. Tk 的基本概念-组件—Tkinter 教程系列03

    Tk 的基本概念-组件-Tkinter 教程系列03 前言 Tk 系列教程: Tkinter教程系列01--引言和安装Tk Tkinter教程系列02--第一个真正的 GUI 程序 通过上一节的程序实 ...

  2. Tkinter教程系列01——引言和安装Tk

    Tkinter教程系列01--引言和安装Tk 首发于我的个人博客 https://chens.life/tkinter-tutorial-chapter-01-introduction-and-ins ...

  3. MongoDB基础教程系列--未完待续

    最近对 MongoDB 产生兴趣,在网上找的大部分都是 2.X 版本,由于 2.X 与 3.X 差别还是很大的,所以自己参考官网,写了本系列.MongoDB 的知识还是很多的,本系列会持续更新,本文作 ...

  4. MongoDB基础教程系列--目录结构

    最近对 MongoDB 产生兴趣,在网上找的大部分都是 2.X 版本,由于 2.X 与 3.X 差别还是很大的,所以自己参考官网,写了本系列.MongoDB 的知识还是很多的,本系列会持续更新,本文作 ...

  5. Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) JAVA日志的前世今生 .NET MVC采用SignalR更新在线用户数 C#多线程编程系列(五)- 使用任务并行库 C#多线程编程系列(三)- 线程同步 C#多线程编程系列(二)- 线程基础 C#多线程编程系列(一)- 简介

    Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) 一.前言 由于本篇文章较长,所以下面给出内容目录方便跳转阅读,当然也可以用博客页面最右侧的文章目录导航栏进行跳转查阅. 一.前言 ...

  6. 《ArcGIS Engine+C#实例开发教程》第一讲桌面GIS应用程序框架的建立

    原文:<ArcGIS Engine+C#实例开发教程>第一讲桌面GIS应用程序框架的建立 摘要:本讲主要是使用MapControl.PageLayoutControl.ToolbarCon ...

  7. 教程和工具--用wxPython编写GUI程序的

    wxPython是个很好的GUI库,对底层的C++库进行了封装,调用起来很方便,尤其是操作前台UI界面和后台多线程,两者配合很方便,做GUI程序最难是写界面尤其是布局. 关于wxPython,自己正在 ...

  8. Python GUI编程(Tkinter)(一)

    tk官网的教程学习: https://tkdocs.com/tutorial/firstexample.html 学习blog: https://www.cnblogs.com/aland-1415/ ...

  9. Python之GUI编程(Tkinter))

    不足之处,还请海涵,请指出不足.本人发布过的文章,会不断更改,力求减少错误信息. 一.重要放在开头:模块 如出现这种错误 ModuleNotFoundError: No module named 'n ...

随机推荐

  1. front-end & web & best code editor

    front-end & web & best code editor 2019 VS Code https://designrevision.com/best-code-editor/ ...

  2. HTML5 Canvas in Action

    HTML5 Canvas in Action canvas 图片处理 视频编辑工具 xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!

  3. TypeScript 3.7 RC & Optional Chaining

    TypeScript 3.7 RC & Optional Chaining https://devblogs.microsoft.com/typescript/announcing-types ...

  4. 最佳搭档:利用 SSH 及其配置文件节省你的生命

    本文转载自最佳搭档:利用 SSH 及其配置文件节省你的生命 导语 SSH 协议是事实上的互联网基石之一.在 SSH 协议出现之前(1995 年由 Tatu Ylonen 设计),通过互联网远程登录其他 ...

  5. JPEG解码——(4)霍夫曼解码

    本篇是该系列的第四篇,主要介绍霍夫曼解码相关内容. 承接上篇,文件头解析完毕后,就进入了编码数据区域,即SOS的tag后的区域,也是图片数据量的大头所在. 1. 解码过程规则描述 a)从此颜色分量单元 ...

  6. mysql导入备份.sql文件时报错总结(还有待完善)

    错误1:ERROR Unknown character set: 'utf8mb4' utf8mb4编码集支持了表情符号,相信处理过社交网络数据的人都有了解.这个mysql5.5以后支持了utf8mb ...

  7. 多Excel文件内容查询工具。

    多Excel文件内容查询工具. 告别繁琐重复的体力劳动,一分钟干完一天的活. 码云 github 下载 当需要在多个Excel表格中查询需要的信息是,一个文件一个文件的去查询非常麻烦. 虽然有其他方法 ...

  8. macOS命令行切换Python版本

    目录 brew安装anaconda3 anaconda3环境变量设置 安装双版本 命令后切换python环境 pip ide vscode set 参考 brew安装anaconda3 brew ca ...

  9. 微信小程序弹出框滚动穿透问题

    1.在你的遮罩层最外层加 catchtouchmove="noneEnoughPeople" 里面是你的方法名2.noneEnoughPeople: function () { c ...

  10. Windows常用快捷键和基本dos命令

    Windows常用快捷键 键盘功能键:Tab,Shift,Ctrl,Alt,空格,Enter,Window... 键盘快捷键: 全选:Ctrl+A 复制: Ctrl+C 粘贴: Ctrl+V 撤销: ...