tkinter 布局管理器

布局管理器

(注:有些组件的大小是不会随着窗口的拉伸变化的)
一个 GUI 应用程序必然有大量的组件,这些组件如何排 布?这时候,就需要使用 tkinter 提供的布局管理器帮助我们 组织、管理在父组件中子组件的布局方式。tkinter 提供了三 种管理器:pack、grid、place。

grid 布局管理器

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即可。
【示例】grid 布局用法-登录界面设计
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()
【示例】通过 grid 布局-实现计算器软件界面。

根据实际简易计算器的按键分布,设计一个相仿的计算器界 面,相应的功能暂不需要实现。
可以设计成一个 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适合于少量的组件排序,所以在使用上是相当简单,一般添加组件后直接使用.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 布局用法,制作钢琴按键布局
#测试 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()必须包含参数,否则控件不会显示
place()方法的选项
在这里插入图片描述
注:in_不是可以随意指定放置的组件的,如果使用in这个参数这个组件必需满足:是其父容器或父容器的子组件,否则会报错

place 函数
在这里插入图片描述

【示例】place 布局管理-扑克牌游戏 demo

在这里插入图片描述

 """扑克牌游戏的界面设计"""
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()
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值