专栏首页疯狂软件李刚快速学会Python tkinter的Pack布局

快速学会Python tkinter的Pack布局

导读

GUI编程就相当于小孩子搭积木,每个积木块应该放在哪里?每个积木块显示为多大?也就是这些大小和位置都需要进行管理,而布局管理器正是负责管理各组件的大小和位置,此外,当用户调整了窗口的大小之后,布局管理器还会自动调整窗口中各组件的大小和位置。

本文详细介绍了Python tkinter编程的pack布局,本文适合Python GUI编程的小白上手。

如果使用Pack布局,意味着当程序向容器中添加组件时,这些组件会依次向后排列,排列方向既可是水平排列,也可是垂直排列。

下面程序简单示范了Pack布局的用法,该程序向窗口中添加了3个Label组件,程序如下。

# Python 2.x使用这行
#from Tkinter import *
# Python 3.x使用这行
from tkinter import *


# 创建窗口并设置窗口标题
root = Tk()
# 设置窗口标题
root.title('Pack布局')
for i in range(3):
    lab = Label(root, text="第%d个Label" % (i + 1), bg='#eeeeee')
    # 调用pack进行布局
    lab.pack()
# 启动主窗口的消息循环
root.mainloop()

上面程序创建了一个窗口,然后使用循环创建了3个Label,并对3个Label使用了pack()方法进行默认的Pack布局。运行该程序,可看到如图1所示的界面。

图1 使用Pack布局

图1使用的是默认的Pack布局,实际上程序在调用pack()方法时同样可传入多个选项,例如通过help(tkinter.Label.pack)命令来查看pack()方法支持的选项可看到如下输出。

>>> help(tkinter.Label.pack)
Help on function pack_configure in module tkinter:


pack_configure(self, cnf={}, **kw)
    Pack a widget in the parent widget. Use as options:
    after=widget - pack it after you have packed widget
    anchor=NSEW (or subset) - position widget according to
                              given direction
    before=widget - pack it before you will pack widget
    expand=bool - expand widget if parent size grows
    fill=NONE or X or Y or BOTH - fill widget if widget grows
    in=master - use master to contain this widget
    in_=master - see 'in' option description
    ipadx=amount - add internal padding in x direction
    ipady=amount - add internal padding in y direction
    padx=amount - add padding in x direction
    pady=amount - add padding in y direction
    side=TOP or BOTTOM or LEFT or RIGHT -  where to add this widget.

从上面显示可以看出,其实pack()方法通常可支持如下选项:

  • anchor:当可用空间大于组件的需求的大小时,该选项决定组件被放置于容器的何处,该选项支持N(北代表上)、E(东代表右)、S(南代表下)、W(西代表左)、NW(西北代表左上)、NE(东北代表右上)、SW(西南代表左下)、SE(东南代表右下)、CENTER(中、默认值为CENTER)这些值。
  • expand:该bool值指定当父容器增大时是否拉伸该组件。
  • fill:设置组件是否沿水平或垂直方向填充,该选项支持NONE、X、Y或BOTH四个值,其中NONE表示不填充,BOTH表示沿着两个方向填充。
  • ipadx:指定该组件在x方向(水平)上的内部留白(padding)。
  • ipady:指定该组件在y方向(水平)上的内部留白(padding)。
  • padx:指定该组件在x方向(水平)与其他组件的间距。
  • pady:指定该组件在y方向(水平)与其他组件的间距。
  • side:设置该组件的添加位置,可设置为TOP、BOTTOM、LEFT或RIGHT这四个值的其中之一。

当程序前面比较复杂时,程序就需要使用多个容器(Frame)进行分开布局,然后再将Frame添加到窗口中。例如如下程序。

# Python 2.x使用这行
#from Tkinter import *
# Python 3.x使用这行
from tkinter import *  
class App:
    def __init__(self, master):
        self.master = master
        self.initWidgets()
    def initWidgets(self):
        # 创建第一个容器
        fm1 = Frame(self.master)
        # 该容器放在左边排列
        fm1.pack(side=LEFT, fill=BOTH, expand=YES)
        # 向fm1中添加3个按钮
        # 设置按钮从顶部开始排列,且按钮只能在垂直(X)方向填充
        Button(fm1, text='第一个').pack(side=TOP, fill=X, expand=YES)
        Button(fm1, text='第二个').pack(side=TOP, fill=X, expand=YES)
        Button(fm1, text='第三个').pack(side=TOP,  fill=X, expand=YES)
        # 创建第二个容器
        fm2 = Frame(self.master)
        # 该容器放在左边排列,就会挨着fm1
        fm2.pack(side=LEFT, padx=10, expand=YES)
        # 向fm2中添加3个按钮
        # 设置按钮从右边开始排列
        Button(fm2, text='第一个').pack(side=RIGHT, fill=Y, expand=YES)
        Button(fm2, text='第二个').pack(side=RIGHT, fill=Y, expand=YES)
        Button(fm2, text='第三个').pack(side=RIGHT, fill=Y, expand=YES)
        # 创建第三个容器
        fm3 = Frame(self.master)
        # 该容器放在右边排列,就会挨着fm1
        fm3.pack(side=RIGHT, padx=10, fill=BOTH, expand=YES)
        # 向fm3中添加3个按钮
        # 设置按钮从底部开始排列,且按钮只能在垂直(Y)方向填充
        Button(fm3, text='第一个').pack(side=BOTTOM, fill=Y, expand=YES)
        Button(fm3, text='第二个').pack(side=BOTTOM, fill=Y, expand=YES)
        Button(fm3, text='第三个').pack(side=BOTTOM, fill=Y, expand=YES) 
root = Tk()
root.title("Pack布局")
display = App(root)
root.mainloop()

上面程序创建了3个Frame容器,其中第一个Frame容器内包含了3个从顶部(TOP)开始排列的按钮,这意味着这3个按钮会从上到下依次排列,且这3个按钮能在水平(X)方向上填充;第二个Frame容器内包含了3个从右边(RIGHT)开始排列的按钮,这意味着这3个按钮会从右向左依次排列;第三个Frame容器内包含3个从底部(BOTTOM)开始排列的按钮,则意味着这3个按钮会从下到上依次排列,且这3个按钮能在垂直(Y)方向上填充。

运行上面程序,看到如图2所示的界面。

图1 复杂的Pack布局

图2为运行效果添加了3个框,分别代表fm1、fm2、fm3(实际上容器是看不到的),此时可以看到fm1内的三个按钮从上到下排列,并且可以在水平方向填充;fm3内三个按钮从下到上排列,并可以在垂直方向填充。

可能有读者会有疑问:fm2内的三个按钮也都设置了fill=Y, expand=YES,这说明它们也应该能在垂直方向填充啊,为啥看不到呢?仔细看fm2.pack(side=LEFT, padx=10, expand=YES)这行代码,这行代码说明fm2本身不在任何方向上填充,因此fm2内的三个按钮都不能填充。

如果希望看到fm2内三个按钮也能在垂直方向填充,可将fm2的pack()方法改为如下代码。

fm2.pack(side=LEFT, padx=10, fill=BOTH, expand=YES)

通过上面不难发现,Pack布局其实还是非常灵活的,它完全可以实现很复杂的用户界面,因为这里有一个界面分解的常识需要说明:无论看上去多么复杂、古怪的界面,其实大多可分解为水平排列和垂直排列,而Pack布局即可实现水平排列,也可是实现垂直排列,然后再通过多个容器进行组合,这样就可以开发出更复杂的界面了。

对于打算使用Pack布局的开发者来说,首先要做的事情是将程序界面进行分解,分解成水平排列的容器和垂直排列的容器——有时候甚至要容器嵌套容器,然后使用多个Pack布局的容器将它们组合在一起。

本文分享自微信公众号 - 疯狂软件李刚(fkbooks),作者:疯狂软件李刚

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-08-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Python的堆操作,是不是要掌握一下

    Python的强大并不在于它的语法,而在于它的库,当你对各种数据结构感到苦恼时,Python提供了各种开箱即用的数据结构。

    疯狂软件李刚
  • 关于Python函数装饰器最简单的说明

    本文是关于Python函数装饰器最简单的介绍,没有废话,没有套路,赤裸裸的一句话就掌握Python函数装饰器。

    疯狂软件李刚
  • 使用Scrapy shell调试一步一步开发爬虫

    很多文章可能直接给你一个爬虫的代码,但这些代码是怎么写出来的,可能往往语焉不详。本文不同,本文并不着重如何写一个爬虫项目,而是一步一步地教会你、一行一行地写出具...

    疯狂软件李刚
  • 周一鸡血 | 编程不好怎么学数据挖掘? | 数说 · 精选

    本文作者谢科,是数说君在知乎认识的一位数据科学大牛,Twitter的Data Scientist,目前正在创业(“用软件定义商家做生意的方式”)。 对于一个编...

    数说君
  • FFmpeg常见的音视频处理方法

    FFmpeg可使用众多参数,参数内容会根据ffmpeg版本而有差异 这里不再赘述,使用前建议先参考参数及编解码器的叙述。此外参数明细可用ffmpeg -h显示;...

    cohen
  • 春节充电系列:李宏毅2017机器学习课程学习笔记03之梯度下降

    【导读】我们在上一节的内容中已经为大家介绍了台大李宏毅老师的机器学习课程的regression问题,其中简要提及了梯度下降(gradient descent),...

    WZEARW
  • 论代码级性能优化变迁之路(一)

    大家好,很久没有和大家一起讨论技术了,那么今天我将和大家一起探讨我负责的某项目的性能变迁之路。

    小程故事多
  • [每日一题]C语言程序设计教程(第三版)课后习题5.6

    题目描述 给出一百分制成绩,要求输出成绩等级‘A’、‘B’、‘C’、‘D’、‘E’。 90分以上为A 80-89分为B 70-79分为C 60-69分为D 60...

    编程范 源代码公司
  • 视频上云网关平台EasyCVR使用海康SDK拉流协议分析

    视频上云网关平台EasyCVR的作用,就是在庞大的项目场景中,将众多不同的分支设备进行统一的管理,能够接入SDK,比如上一篇博文我就为大家介绍了EasyCVR支...

    EasyNVR
  • Appium同时连接多台手机进行测试(多

      开启多线程后,发现app启动后,用例就停止了;且启动app对应的手机不能正确对应,用例中是A手机跑A用例,结果启动了B手机跑A用例报错。

    py3study

扫码关注云+社区

领取腾讯云代金券