Python grid布局的简介与细节进阶 (2)

上一节我们介绍了tkinter库(Python标准GUI库)grid布局的基本概念。从本节开始,我们用一个很简单的样例程序,来演示grid布局的使用以及一些有意思的细节。

1. 样例程序简介

1.1 样例程序说明

这个样例程序(CreateTagFiles)的功能很简单:在指定目录下创建若干以指定短语为文件名的空文件。
这些空文件可以被视为该目录的标签,能够很方便地被Everything等文件搜索工具检索到。比如,你在某CD音频文件目录下创建了“古典音乐”,“交响曲”,“海顿”,“卡拉扬”,“柏林爱乐”等空文件,那么当你用Everything检索“海顿”的时候,就能一下子找到包含这个目录在内的、所有放置了“海顿”标签文件的文件夹了。

1.2 样例程序GUI设计

从上面的需求可见,GUI上需包括如下组件:

  • 用户输入:需要指定特定目录、指定若干短语 —— 简单起见,使用两个文本输入框就好了;
  • 用户确定:确定生成这些这些文件 —— 需要一个“Create”按钮;
  • 完成退出 —— 需要一个“Close”按钮;

因此,界面设计简图如下:

TagCreator 界面设计

按照这个设计,我们很可以自然地看出,屏幕上半部每行要容纳三个组件(文本提示、文字输入框、滚动条),而下半部每行要容纳两个组件(两个按钮)。

如果我们将整个屏幕作为一个grid来设计的话,grid至少要有3列。但是,3列的排版又会让下面的两个按钮难以排列整齐。有什么好办法吗?

2. 整体布局 - grid与frame的配合使用

当屏幕不同位置需要不同数量的行列时,frame能起到很大作用。

2.1 frame简介

一个frame就是屏幕上的一块矩形区域,frame虽然是一种部件(widget),但一般总是被用来容纳、组织其他部件的。

注意:frame是部件(widget)的一种,部件是出现在屏幕上的一个具体物;grid是布局(layout)的一种,是部件如何被组织的一种体系、方法。两者完全不同。

在tkinter中,主窗口本身就是一个frame。

tkinter主窗口的常规写法是:

1
2
3
import tkinter
top = tkinter.Tk()
top.mainloop()

但我更喜欢按照一般部件的方法来创建frame,即:

  1. 创建部件
  2. 放置部件

代码如下:

1
2
3
4
import tkinter
frm_root = tkinter.Frame()
frm_root.grid()
frm_root.mainloop()

grid()方法的简介可以参见上一节Python grid布局的简介与细节 (1)

2.2 frame与grid的配合使用

frame之所以常常被用来与grid配合使用,是因为每一个frame都可以有自己特定的grid布局(即不同的行列数)。

这样,在样例程序中,我们可以在主frame上放置两个子frame:上面的子frame有2行3列,下面的子frame是1行2列。而这两个子frame在主frame中则是2行1列。

这部分代码1如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import tkinter as tk
# 主窗口
frm_root = tk.Frame()
frm_root.grid()
# 主窗口第0行第0列 - 用户输入frame
frm_input = tk.Frame(frm_root)
frm_input.grid(row=0)
# 主窗口第1行第0列 - 用户按钮frame
frm_button = tk.Frame(frm_root)
frm_button.grid(row=1)
# 启动界面
frm_root.mainloop()

执行2上述代码,结果如下:

只有空框架的主界面

我们仅仅放置了几个空frame,既没有在其中放置其他部件,也没有指定frame的长、宽,所以屏幕上自然什么都看不到。

我们按照前面的设计,在“用户输入frame(主窗口第0行第0列 )”中填入相关部件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 用户输入frame内容
# 用户输入frame的第0行第0列 - Tags标签
lbl_tags = tk.Label(frm_input, text="Tags")
lbl_tags.grid(row=0, column=0)
# 用户输入frame的第0行第1列 - Tags输入框
txt_tags = tk.Text(frm_input, width=27, height=10)
txt_tags.grid(row=0, column=1)
# 用户输入frame的第0行第2列 - Tags输入框的滚动条
srb_tags = tk.Scrollbar(frm_input)
srb_tags.grid(row=0, column=2)
# 用户输入frame的第1行第0列 - Path标签
lbl_path = tk.Label(frm_input, text="Directory")
lbl_path.grid(row=1, column=0)
# 用户输入frame的第1行第1、2列 - Path输入框
etr_path = tk.Entry(frm_input, width=30)
etr_path.grid(row=1, column=1, columnspan=2)

然后再在“按钮frame(主窗口第1行第0列)”中填入相关部件(这两段向frames中填充部件的代码放到主程序的frm_root.mainloop()语句之前即可):

1
2
3
4
5
6
7
# 按钮frame内容
# 按钮frame的第0行第0列 - “Create”按钮
btn_create = tk.Button(frm_button, text='Create', width=5)
btn_create.grid(row=0, column=0)
# 按钮frame的第0行第1列 - “Close”按钮
btn_close = tk.Button(frm_button, text='Close', width=5)
btn_close.grid(row=0, column=1)

执行上述代码,结果如下:

填充了所有部件的主界面

不错,现在所有的部件都已经差不多就位了,剩下一些精细的调整,我们下一篇再说。


尾注


  1. 本系列博文中代码使用的Python版本为3.6.3

  2. 本系列博文中代码运行的操作系统为Windows 7 Ultimate SP1

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器