如何使用pack布局界面tkinter组件?

2019年9月22日 / 34次阅读 / Last Modified 2019年9月22日
tkinter

用Python写了一段时间的GUI程序,使用的是默认的tkinter模块,一直使用grid方法来做界面布局,后来遇到了问题,才发现原来pack方法才是最简单最好用的(个人理解)。本文介绍如何使用pack方法布局界面。

每一个tkinter组件,都有pack方法(也都有grid和plack方法)。pack,就是打包的意思,将组件打包进界面。pack方法,就是按照代码的先后顺序,将组件一个个的从上到下(默认)摆放在GUI界面中。

from tkinter import *

root = Tk()
for i in range(5):
    Label(root, text=str(i), relief=GROOVE).pack(fill=BOTH, expand=True)
root.mainloop()

fill=BOTH表示按X和Y两个方向随控件延伸,expand=True表示控件随父组件的尺寸扩展而扩展。有这两个属性的定义,比较容易看到效果。pack更多属性,请在Python解释器中使用 help(tkinter.Label.pack) 查看。上面代码运行效果如下:

pack方法默认按从上到下顺序排列组件
pack方法默认按从上到下顺序排列组件

我们可以通过side属性值,来改变默认的从上到下排雷的方法,side的可选值有LEFT,RIGHT,BOTTOM,TOP(默认)。我们试一下side=RIGHT的效果,代码和效果如下:

from tkinter import *

root = Tk()
for i in range(5):
    Label(root, text=str(i), relief=GROOVE).pack(side=RIGHT, fill=BOTH, expand=True)
root.mainloop()
pack的side属性为RIGHT时的效果
pack的side属性为RIGHT时的效果

以上就是使用pack,将组件一个个按右排列的效果。

在来一个比较复杂的,代码和效果如下:

from tkinter import *

root = Tk()
for i in range(5):
    Label(root, text=str(i), relief=GROOVE).pack(fill=BOTH, expand=True)
for i in range(5):
    Label(root, text=str(i), relief=GROOVE).pack(side=RIGHT, fill=BOTH, expand=True)
for i in range(5):
    Label(root, text=str(i), relief=GROOVE).pack(side=BOTTOM, fill=BOTH, expand=True)
for i in range(5):
    Label(root, text=str(i), relief=GROOVE).pack(side=LEFT,fill=BOTH, expand=True)
root.mainloop()
复杂的pack效果
复杂的pack效果

我提炼出pack方法下一个位置的概念:上面的代码,先试从上到下pack,因此下一个位置在总下面;第2个循环,采用side=RIGHT,于是就在下面的那个位置里从右开始排列;这样下一个位置就在最后一个4的右边;然后第3个循环,采用side=BOTTOM,从下往上排列,得到下一个位置在第3个4的上面;最后一个循环,采用side=LEFT,从左到右填满了中间那个狭小的空间!

pack方法简单的地方在于:

  • 不用计算,使用grid和place都要计算位置,行列或者坐标,使用pack不用计算,只有上下左右的关系,一个个按设定顺序放上去。这个特点在有GUI分支的时候,特别方别,比如用一个变量控制GUI界面的生成,有的时候都几个组件,有的时候少几个,不用计算位置,pack轻松搞定。
  • 配合Frame,使用pack,几乎任何样式的GUI界面都能轻松搞定。Frame是组件的容器,Frame之间也可以使用pack,Frame之内的组件依然可以使用pack。

最后,来一个超级复杂的用pack方法构建的GUI界面,使用了两层Frame,代码和效果如下:

from tkinter import *

def drawLabels(master=None):
    for i in range(5):
        Label(master, text=str(i), relief=GROOVE).pack(fill=BOTH, expand=True)
    for i in range(5):
        Label(master, text=str(i), relief=GROOVE).pack(side=RIGHT, fill=BOTH, expand=True)
    for i in range(5):
        Label(master, text=str(i), relief=GROOVE).pack(side=BOTTOM, fill=BOTH, expand=True)
    for i in range(5):
        Label(master, text=str(i), relief=GROOVE).pack(side=LEFT,fill=BOTH, expand=True)

root = Tk()
# frame row 0
frame_0 = Frame(root)
frame_0.pack()
# frame left
frame_left = Frame(frame_0)
frame_left.pack(side=LEFT)
drawLabels(frame_left)
# frame right
frame_right = Frame(frame_0)
frame_right.pack(side=LEFT)
drawLabels(frame_right)
# frame row 1
frame_1 = Frame(root)
frame_1.pack(fill=BOTH, expand=True)
drawLabels(frame_1)
root.mainloop()
用两层Frame配合pack构建的界面
用两层Frame配合pack构建的界面

这段代码frame_0中包含了frame_left和frame_right,而frame_1中就直接调用drawLabels函数了。注意frame_1的pack方法中使用的参数。

使用pack方面画tkinter的GUI界面,一般采用限制窗口大小的缩放,如果允许窗口大小的变化,可能导致各组件大小变得极其不协调,或者窗口内出现大片空白尴尬的区域。

-- EOF --

本文链接:https://www.pynote.net/archives/1187

留言区

《如何使用pack布局界面tkinter组件?》有1条留言

电子邮件地址不会被公开。 必填项已用*标注

  • 麦新杰

    pack方法在对齐方面有些不足,这方面用grid来弥补吧,用pack放frame,在frame中使用grid精准对齐。 [回复]


前一篇:
后一篇:

More

麦新杰的Python笔记

Ctrl+D 收藏本页


©Copyright 麦新杰 Since 2019 Python笔记

go to top