0️⃣前言
此文章代码都在Github:3-窗口控件配置管理员/pack方法别忘了⭐️呀
做一个应用程序,肯定需要更多的widget控件,所以这时候就牵扯到了如何将这些widget控件配置到 容器 或 窗口 内。在设计GUI程序时,可以使用三种方法包装和定为各组件在 容器 或 窗口 内的位置,这三个方法又称窗口控件配置管理员(Widget Layout Manager),通常叫做布局方法。
一共有三种布局方法:pack、grid和place,最常用的是pack方法,本章介绍pack方法
窗口控件配置管理员
pack方法的语法格式如下
***.pack(options, ...)
options参数可以是如下属性:
- side
- fill
- padx/pady
- ipadx/ipady
- anchor
下面将详细说明
1️⃣side参数
可以垂直或水平配置控件,可以设置控件的排列顺序
#coding:UTF-8
#ch1.py
from tkinter import *
root = Tk()
root.title("普通设置控件")
Label(root, text="Tkinter", bg="lightyellow").pack()
#第一个标签
#这些标签不需要保存在变量中,设置好直接布局
Label(root, text="wxPython", bg="lightgreen").pack()
Label(root, text="PyQt", bg="lightblue").pack()
root.mainloop()
如果窗口中有多个控件,pack会自动让控件从上往下排列显示,这是默认设置。也可以使用side参数改变排列方式,此参数取值如下
- TOP:默认值,由上往下排列
- BOTTOM:由下往上排列
- LEFT:从左往右排列
- RIGHT:从右往左排列
重新改造,使用side,并让标签的宽度都为15
#coding:UTF-8
#ch2.py --ch1.py 2.0
from tkinter import *
root = Tk()
root.title("普通设置控件")
Label(root, text="Tkinter", bg="lightyellow", width=15).pack(side=BOTTOM)
#第一个标签
#这些标签不需要保存在变量中,设置好直接布局
Label(root, text="wxPython", bg="lightgreen", width=15).pack(side=BOTTOM)
Label(root, text="PyQt", bg="lightblue", width=15).pack(side=BOTTOM)
root.mainloop()
再改成LEFT
#coding:UTF-8
#ch3.py -- ch2.py->side->LEFT
from tkinter import *
root = Tk()
root.title("普通设置控件")
Label(root, text="Tkinter", bg="lightyellow", width=15).pack(side=LEFT)
#第一个标签
#这些标签不需要保存在变量中,设置好直接布局
Label(root, text="wxPython", bg="lightgreen", width=15).pack(side=LEFT)
Label(root, text="PyQt", bg="lightblue", width=15).pack(side=LEFT)
root.mainloop()
混合使用side
#coding:UTF-8
#ch4.py -- ch3.py->side->混合使用
from tkinter import *
root = Tk()
root.title("普通设置控件")
Label(root, text="Tkinter", bg="lightyellow", width=15).pack()
#第一个标签
#这些标签不需要保存在变量中,设置好直接布局
Label(root, text="wxPython", bg="lightgreen", width=15).pack(side=RIGHT)
Label(root, text="PyQt", bg="lightblue", width=15).pack(side=LEFT)
root.mainloop()
2️⃣padx / pady参数
可以使用padx/pady参数设定控件边界与容器(可以想成窗口边界)的距离或是控件边界间的距离。在默认环境下窗口控件间的距离是 1 像素,如果希望有适度间距,可以设置padx/pady,代表水平间距/垂直间距
实例:
#coding:UTF-8
from tkinter import *
root = Tk()
root.title("relief")
Label(root, text="flat", relief="flat").pack(side=LEFT, pady=5, padx=4, ipadx=10, ipady=10)
Label(root, text="groove", relief="groove").pack(side=LEFT, pady=5, padx=4, ipadx=10, ipady=10)
Label(root, text="raised", relief="raised").pack(side=LEFT, pady=5, padx=4, ipadx=10, ipady=10)
Label(root, text="ridge", relief="ridge").pack(side=LEFT, pady=5, padx=4, ipadx=10, ipady=10)
Label(root, text="solid", relief="solid").pack(side=LEFT, pady=5, padx=4, ipadx=10, ipady=10)
Label(root, text="sunken", relief="sunken").pack(
side=LEFT, pady=5, padx=4, ipadx=10, ipady=10)
root.mainloop()
用relief参数实现各种标签的边框,ipadx和ipady等会讲,运行结果
3️⃣ipadx / ipady参数
ipadx/ipady是调整内部距离的,padx/pady是调整外部距离的,还是刚才的程序运行结果,再次分析
4️⃣anchor参数
可以设定Widget控件在窗口中的位置,参数如下
实例:
#coding: UTF-8
#ch7.py anchor
from tkinter import *
root = Tk()
root.title("ch7.py")
root.geometry("300x180")
okbtn = Button(root, text="OK",
font="Times 20 bold",
fg="white", bg="blue")
okbtn.pack(anchor=S, side=RIGHT,
padx=10, pady=10)
root.mainloop()
原本书中写的是Label的,因为这个是鉴于刚学了Label其他的都不知道的同学看的,我觉得既然是OK,Button更好一些吧
那么再加上一个NO键是不是更好?
#coding: UTF-8
#ch8.py anchor + NO BTN
from tkinter import *
root = Tk()
root.title("ch7.py")
root.geometry("300x180")
okbtn = Button(root, text="OK",
font="Times 20 bold",
fg="white", bg="blue")
okbtn.pack(anchor=S, side=RIGHT,
padx=10, pady=10)
nobtn = Button(root, text = "NO",
font="Times 20 bold",
fg="white", bg="red")
nobtn.pack(anchor=S, side=RIGHT,
pady=10)
root.mainloop()
5️⃣fill参数
此参数是告诉pack管理程序,设置控件填满所分配容器区间的方式,如果是fill=X
表示控件可以填满所分配空间X轴不留白,反之亦然,如果是fill=BOTH
表示控件可以填满所分配空间的X轴和Y轴。fill的默认值是None,表示保持原始大小。
实例:(改编第一个ch1.py)
#coding:UTF-8
#ch9.py fill
from tkinter import *
root = Tk()
root.title("普通设置控件")
Label(root, text="Tkinter", bg="lightyellow").pack(fill=X)
#第一个标签
#这些标签不需要保存在变量中,设置好直接布局
Label(root, text="wxPython", bg="lightgreen").pack()
Label(root, text="PyQt", bg="lightblue").pack(fill=X)
root.mainloop()
如果所分配容器空间已经满了,则使用fill没有任何作用,将wxPython那个标签设置为.pack(fill=Y)
不会有任何效果。
6️⃣expand参数
expand参数可设定Widget控件是否填满额外的父容器空间,默认是False(或0),表示不填满,如果是True(或是1)则填满。这很重要!
不管怎么设置fill参数,其结果都没有填满整个窗口,于是expand隆重出场!
#coding:UTF-8
#ch9.py fill
from tkinter import *
root = Tk()
root.title("expand")
Label(root, text="Tkinter", bg="lightyellow").pack(side=LEFT, fill=Y)
#第一个标签
#这些标签不需要保存在变量中,设置好直接布局
Label(root, text="wxPython", bg="lightgreen").pack(fill=X)
Label(root, text="PyQt", bg="lightblue").pack(fill=BOTH, expand=True) #设置可以变化
root.mainloop()
#coding:UTF-8
#ch9.py fill
from tkinter import *
root = Tk()
root.title("expand")
Label(root, text="Tkinter", bg="lightyellow").pack(
side=LEFT, fill=Y)
#第一个标签
#这些标签不需要保存在变量中,设置好直接布局
Label(root, text="wxPython", bg="lightgreen").pack(fill=BOTH, expand=True)
Label(root, text="PyQt", bg="lightblue").pack(fill=BOTH, expand=True) #设置可以变化
root.mainloop()
7️⃣pack参数
- forget()——隐藏Widget控件,可以用
pack(option, ...)
复原 - info()——传回pack选项的对应值
- size()——传回Widget控件的大小
- …………更多问度娘😏
PS:一个程序只能有一种窗口布局,如果使用pack,就不能使用grid、place了
再PS:别忘了点赞留言收藏呀😸哦还要关注啊🌠
*还PS:此文章代码都在Github:Coding-Notes/Python-Notes/学习/图形界面开发学习笔记/PythonGUI设计tkinter菜鸟编程书/3-窗口控件配置管理员/pack方法别忘了star仓库!