赞
踩
(注:有些组件的大小是不会随着窗口的拉伸变化的)
一个 GUI 应用程序必然有大量的组件,这些组件如何排 布?这时候,就需要使用 tkinter 提供的布局管理器帮助我们 组织、管理在父组件中子组件的布局方式。tkinter 提供了三 种管理器:pack、grid、place。
grid 表格布局,采用表格结构组织组件。子组件的位置由 行和列的单元格来确定,并且可以跨行和跨列,从而实现复杂的布局。
grid()方法提供的选项
grid 函数表
函数名 | 描述 |
---|---|
grid_slaves() | 以列表方式返回本控件的所有子控件对象 |
grid_configure(option=value) | 给grid布局管理器设置属性,使用属性(option)= 取值(value)方式设置 |
grid_propagate(boolean) | 设置为True表示父控件的几何大小由子控件决定(默认值),反之则无关 |
grid_info() | 返回提供的选项所对应的值 |
grid_forget() | 将控件隐藏并且忽略原有设置,对象依旧存在,可以用grid(option, …),将其显示 |
grid_remove () | 和grid_forget()类似。不过会记住当前的选项。重新.grid之后,会使用当前的选项 |
grid_location(x, y) | 设定控件在屏幕中相对于容纳单元的(x,y)坐标,并返回grid系统中的哪个单元包含了该坐标(column,row) |
size() | 返回组件所包含的单元格,揭示组件大小 |
grid_bbox(column=None, row=None, col2=None, row2=None) | 返回一个有四个元素的元组,用来描述控件内一些或者全部单元的边界。返回的前两个数为左上方区域的x,y坐标,后两个数为宽度和高度。 如果只传递了 column 和 row 参数,返回的参数描述的是该行列的单元的大小。如果传递了 col2 和 row2 参数,返回的参数描述的就是从 column 列 到 col2 列,以及从 row 行 到 row2 行总体区域的大小。 |
grid_rowconfigure(index, **options) | –设置行的属性 – 注意:设置的是该组件所拥有的grid序列 见行属性设定表 |
grid_columnconfigure(index, **options) | –设置列的属性-- 注意:设置的是该组件所拥有的grid序列 见列属性设定表 |
如果要充满整个单元格,需要用这两个函数
表:行属性设定表
选项 | 含义 |
---|---|
minsize | 指定该行的最小高度 |
pad | 指定该行中最大网格的垂直边距 |
weight | –指定行与行之间的相对距离-- 默认值是0-- 说明:初创建窗口的时候,grid会自动根据组件的尺寸分配窗口的尺寸,当你拉伸窗口的尺寸就会有空白显示出来。这个选项正是指定行与行·之间是否填充空白,默认是不填充的。另外,该选项的值是指定填充空白的倍数,例如weight=2的列会比weight=1的列填充多一倍的空白,所以需要平均填充的话,只需要所有的列都设置为weight=1即可。 |
from tkinter import * from tkinter import messagebox import random class Application(Frame): def __init__(self, master=None): super().__init__(master) # super()代表的是父类的定义,而不是父类对象 self.master = master self.pack() self.createWidget() def createWidget(self): """通过 grid 布局实现登录界面""" self.label01 = Label(self,text="用户名") self.label01.grid(row=0,column=0) self.entry01 = Entry(self) self.entry01.grid(row=0,column=1) Label(self,text="用户名为手机号").grid(row=0,column=2) Label(self, text="密码").grid(row=1, column=0) Entry(self, show="*").grid(row=1, column=1) Button(self, text="登录").grid(row=2, column=1,sticky=EW) Button(self, text="取消").grid(row=2, column=2,sticky=E) if __name__ == '__main__': root = Tk() root.geometry("400x90+200+300") app = Application(master=root) root.mainloop()
根据实际简易计算器的按键分布,设计一个相仿的计算器界 面,相应的功能暂不需要实现。
可以设计成一个 7 行 4 列的表格布局,然后 将相应的按钮放置进去即可。
from tkinter import * from tkinter import messagebox import random class Application(Frame): def __init__(self, master=None): super().__init__(master) # super()代表的是父类的定义,而不是父类对象 self.master = master self.pack() self.createWidget() def createWidget(self): """通过 grid 布局实现计算器的界面""" btnText = ( ("MC","M+","M-","MR"), ("C","±","/","✖ "), (7,8,9,"-"), (4,5,6,"+"), (1,2,3,"="), (0,".") ) Entry(self).grid(row=0,column=0,columnspan=4,pady=10) for rindex,r in enumerate(btnText): for cindex,c in enumerate(r): if c == "=": Button(self,text=c,width=2).grid(row=rindex+1,column=cindex,rowspan=2,sticky=NSEW) elif c == 0: Button(self,text=c,width=2).grid(row=rindex+1,column=cindex,columnspan=2,sticky=NSEW) elif c == ".": Button(self,text=c,width=2).grid(row=rindex+1,column=cindex+1,sticky=NSEW) else: Button(self,text=c,width=2).grid(row=rindex+1,column=cindex,sticky=NSEW) if __name__ == '__main__': root = Tk() root.geometry("200x200+200+300") app = Application(master=root) root.mainloop()
pack 按照组件的创建顺序将子组件添加到父组件中,按 照垂直或者水平的方向自然排布。如果不指定任何选项,默 认在父组件中自顶向下垂直添加组件。
pack适合于少量的组件排序,所以在使用上是相当简单,一般添加组件后直接使用.pack()方法即可。但是如果想要对复杂的组件进行布局,那就要使用grid()或者Frame框架。
(子控件可以覆盖父控件(使用参数 in_))
pack()方法提供的选项
【老鸟建议】如上列出了 pack 布局所有的属性,但是不需要挨个熟悉,了解基本的即可。pack 适用于简单的垂直或水平排布,如果需要复杂的布局可以使用 grid 或 place
pack的函数包括:
slaves()函数返回本控件的所有子控件对象。如果不使用pack(),就算已经实例化了子控件,slaves()也不会输出没有pack()的子控件。比如b4就不会输出。而b2和b3会被认为是b1的子控件
propagate(flag) 函数————该函数决定父控件的大小是否与子控件有关。如果flag是True则父控件的大小为包括子控件的大小。如果flag是False,则表示父控件的大小与子控件无关。不过geometry()会让propagate()失效,窗口的大小由geometry()决定(会改变图像的位置以及完整性 改变组件的放置位置,会从头开始放)
#测试 pack 布局管理
from tkinter import *
root = Tk();root.geometry("700x220")
#Frame 是一个矩形区域,就是用来放置其他子组件
f1 = Frame(root)
f1.pack()
f2 = Frame(root);f2.pack()
btnText = ("流行风","中国风","日本风","重金属","轻音乐")
for txt in btnText:
Button(f1,text=txt).pack(side="left",padx="10")
for i in range(1,20):
Button(f2,width=5,height=10,bg="black" if i%2==0 else"white").pack(side="left")
root.mainloop()
place 布局管理器可以通过坐标精确控制组件的位置,适用 于一些布局更加灵活的场景。
注:必须设定父控件的大小(不是主窗口)。否则,不会显示该控件和其子控件。place用起来很繁琐。需要注意很多事情。好处就是可以随心所欲的摆放控件。place()必须包含参数,否则控件不会显示
place()方法的选项
注:in_不是可以随意指定放置的组件的,如果使用in这个参数这个组件必需满足:是其父容器或父容器的子组件,否则会报错
place 函数
"""扑克牌游戏的界面设计""" from tkinter import * class Application(Frame): def __init__(self, master=None): super().__init__(master) # super()代表的是父类的定义,而不是父类对象 self.master = master self.pack() self.createWidget() def createWidget(self): """通过 place 布局管理器实现扑克牌位置控制""" # self.photo = PhotoImage(file="imgs/puke/puke1.gif") # self.puke1 = Label(self.master,image=self.photo) # self.puke1.place(x=10,y=50) self.photos =[PhotoImage(file="imgs/puke/puke"+str(i+1)+".gif") for i in range(10)] self.pukes =[Label(self.master,image=self.photos[i]) for i in range(10)] for i in range(10): self.pukes[i].place(x=10+i*40,y=50) # 为所有的 Label 增加事件处理 self.pukes[0].bind_class("Label","<Button-1>",self.chupai) def chupai(self,event): print(event.widget.winfo_geometry()) print(event.widget.winfo_y()) if event.widget.winfo_y() == 50: event.widget.place(y=30) else: event.widget.place(y=50) if __name__ == '__main__': root = Tk() root.geometry("600x270+200+300") app = Application(master=root) root.mainloop()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。