GUI的终极选择:Tkinter13:布局管理器

   ※什么是布局管理器?就是负责管理各大组件的排列,Tkinter提供了三大布局管理器,分别是pack、grid和place,下面一个一个介绍

##pack
   ※ pack:pack 是按添加顺序排列组件

   对比 grid 管理器,pack 更适用于少量组件的排列,但它在使用上更加简单(就像我们前边所有的例子中,展示一个组件我们一般都直接使用 .pack(),多简单~)。如果你需要创建相对复杂的布局结构,那么建议是使用多个框架(Frame)结构构成,或者使用 grid 管理器实现。

   注意:不要在同一个父组件中混合使用 pack 和 grid,因为 Tkinter 会很认真地在那儿计算到底先使用那个布局管理器…以至于你等了半个小时,Tkinter 还在那儿纠结不出结果!

   下面来演示将一个组件放进另一个组件里,并且要求是填充另一个组件

from tkinter import *

root = Tk()

listbox =Listbox(root)
listbox.pack(fill=BOTH,expand=True)

for i in range(10):
     listbox.insert(END,str(i))

mainloop()

在这里插入图片描述                     在这里插入图片描述
   (解析:这里用的是listbox组件放到root窗口也是组件,实例化好后,接着用pack来布局,listbox.pack(fill=BOTH,expand=True),fill=BOTH就是让他填充满他的父组件,然后在设置一个expand选项为True,然后用insert方法往listbox里面添加,运行就可以了

   生成之后呢,可以看到listbox跟root窗口是紧贴在一起的,因为我们用了fill选项来告诉pack布局管理器,里边的组件的熬紧挨着他的老爸,紧挨着他的父组件,然后expand=True就是说当延长拉伸窗口的时候,他里面的组件会跟着填充,所以expand选项就是告诉窗口管理器,将父组件的额外空间也给填满,如图二)

   上面提到,pack是按照组件的添加顺序依次排列的,那先来看看他是横向排列还是纵向排列

from tkinter import *

root = Tk()

Label(root,text="red",bg="red",fg="white").pack(fill=X)
Label(root,text="green",bg="green",fg="black").pack(fill=X)
Label(root,text="blue",bg="blue",fg="white").pack(fill=X)

mainloop()

在这里插入图片描述
   (解析:这里就是连续创建了三个Label标签,然后用pick依次放入到root窗口中去,其中选项中bg表示背景色,fg表示前景色,即字体的颜色,fill=X表示横向填充,BOTH就是横向和纵向,Y就是纵向填充,运行后可以看到他是纵向填充的)

   那我们就可以使用 side 选项来实现横向填充,都设置为LEFT,他就每一次都往左边去挤,他就是横向填充了
在这里插入图片描述

##grid
   (grid 管理器可以说是 Tkinter 这三个布局管理器中最灵活多变的。如果你只希望学习其中一个布局管理器,然后学精它,那么 grid 绝对是首选。很多tkinter的文档里边甚至没有palce和pack,只有一个grid管理器的说明,因为他特别灵活,特别重要。

   当你在设计对话框的时候,使用 gird 尤其便捷,如果你此前一直用pack来构造窗口的布局,那么学习完 grid 你会悔恨当初为啥不早学它。使用一个 grid 就可以简单的实现你用很多个框架和 pack 搭建起来的效果。;同样要注意的pack 和 grid不能在同一父组件混合使用)
   ※ grid:grid 是按行/列形式排列组件

   使用 grid 排列组件,只需告诉它你想要将组件放置的位置(行/列,row 选项指定行,cloumn 选项指定列)。此外,你并不用提前指出网格(grid 分布给组件的位置称为网格)的尺寸,因为管理器会自动计算。

from tkinter import *

root = Tk()

Label(root,text="用户名").grid(row=0,column=0)
Label(root,text="密码").grid(row=1,column=0)

Entry(root).grid(row=0,column=1)
Entry(root,show="*").grid(row=1,column=1)

mainloop()

在这里插入图片描述
   (解析:这个例子就是对两个Label组件和两个输入组件进行布局构成一个用户输入的界面,直接使用grid,然后在里边指定行和列,如果column是0也可以省略不写,这里就是两个Label分组是在0行0列和1行0列,两个输入框的位置分别是0行1列和1行1列,第二个输入框设置了show选项等于*,那么输入密码就看到*,这个可以自己指定)

   默认情况下组件会居中显示在对应的网格里,你可以使用 sticky 选项来修改这一特性。该选项可以使用的值有 “e”,“w”,“s”,“n”(ewsn 分别表示东西南北,即上北下南左西右东)以及它们的组合。因此,我们可以通过 sticky = “w” 使得 Label 左对齐:   (就是说让"用户名"和"密码"左对齐,因为当Label一多,全部左对齐会显得更整齐)
在这里插入图片描述

   有时候你可能需要用几个网格来放置一个组件,可以做到吗?当然可以,你只需要指定 rowspan 和 columnspan 就可以实现跨行和跨列的功能:

from tkinter import *

root = Tk()



Label(root,text="用户名").grid(row=0,column=0,sticky=W)
Label(root,text="密码").grid(row=1,column=0,sticky=W)

photo = PhotoImage(file="test.gif")
Label(root,image=photo).grid(row=0,column=2,rowspan=2,padx=5,pady=5)

Entry(root).grid(row=0,column=1)
Entry(root,show="*").grid(row=1,column=1)

Button(root,text="提交",width=10).grid(row=2,columnspan=3,pady=5)

mainloop()

在这里插入图片描述

   (解析:这里就是在上个例子的基础下,在右边在加一个Label组件,这个组件放个photoImage图片对象,因为他要占两行,所以设置rowspan选项=2,这样就相当于他的row=0和row=1,同时跨了两行

   然后不想让图片跟文字挨在一块,这样看起来不好看,就可以通过padx和pady来设置他的内边距,接着可以再来完善一下,再来个提交的按钮,然后为了好看,这个按钮就应该占三行,用columnspan选项来设置,最后还设置了个pady选项,让他不会太靠近下边界)

##place 管理器
   ※ place:place 则允许程序员指定组件的大小和位置

   通常情况下不建议使用 place 布局管理器,因为对比起 pack 和 grid,place 要做更多的工作。不过存在即合理,place 在一些特殊的情况下可以发挥妙用。grid和pack是无法代替的

   比如想要将子组件显示在父组件的正中间:

from tkinter import *

root = Tk()

def callback():
     print("正中靶心!")
     
Button(root,text="点我",command = callback).place(relx=0.5,rely=0.5,anchor=CENTER)

mainloop()

在这里插入图片描述

   (解析:这里就是利用place来布局将一个按钮组件显示在父组件的正中间,其中他的relx=0.5,rely=0.5选项就是相当父组件的位置(坐标),0.5表示是正中间,1表示是左边,0表示是最左边,然后还设置一个anchor选项为CENTER,表示居中显示,那么运行后,无论怎么变,他都是在正中央的位置)

   在某种情况下,或许你希望一个组件可以覆盖另一个组件,那么 place 又可以派上用场了。下边例子我们演示用 Button 覆盖 Label 组件:

from tkinter import *

root = Tk()

photo = PhotoImage(file="test.gif")
Label(root,image=photo).pack()

def callback():
     print("正中靶心!")
     

Button(root,text="点我",command = callback).place(relx=0.5,rely=0.5,anchor=CENTER)

mainloop()

在这里插入图片描述
   (解析:需要注意的是pack和place是可以混用的,这里Label就是用pack来布局的,然后从截图可以看出,图片中间多了个按钮,place就是让我们实现这些变态的功能)

   从刚刚第一个例子应该不难看出,relx 和 rely 选项指定的是相对于父组件的位置,范围是 00 ~ 1.0,因此 0.5 表示位于正中间。那么 relwidth 和 relheight 选项则是指定相对于父组件的尺寸:

from tkinter import *

root = Tk()

Label(root,bg="red").place(relx=0.5,rely=0.5,relheight=0.75,relwidth=0.75,anchor=CENTER)
Label(root,bg="green").place(relx=0.5,rely=0.5,relheight=0.5,relwidth=0.5,anchor=CENTER)
Label(root,bg="yellow").place(relx=0.5,rely=0.5,relheight=0.25,relwidth=0.25,anchor=CENTER)
mainloop()

在这里插入图片描述在这里插入图片描述
   (解析:这里就是设置了三个Label组件,然后用place来布局,分别把他们组件的的相对高度和宽度分别设置为相对root窗口的3/4,1/2,和1/4,截图可以看到,当拖动root窗口变化,里边三个Label组件也会相应的变化)

发布了250 篇原创文章 · 获赞 117 · 访问量 29万+

猜你喜欢

转载自blog.csdn.net/w15977858408/article/details/104221374