tkinter-place布局详解
前文介绍了tkinter中的grid布局,相信对tkinter的布局套路有了进一步的了解。本文将介绍另一种布局类place。同样,展示布局类与控件类的类间关系:文章目录placexyrelxrelywidthheightanchorplaceplace(cnf={}, **kw)place和其他两种布局方式相比,更加"自由"但是需要做的事情也多。布局一般就是设置子控件相对于父控件的 起始位置、宽和
前文介绍了tkinter中的grid布局,相信对tkinter的布局套路有了进一步的了解。本文将介绍另一种布局类place。
同样,展示布局类与控件类的类间关系:
place
place(cnf={}, **kw)
place和其他两种布局方式相比,更加"自由"但是需要做的事情也多。布局一般就是设置子控件相对于父控件的 起始位置、宽和高。在pack、grid的布局方式中,起始位置、宽和高都会给默认配置,所以使用起来会更"简",代价就是"控制权"减少。所以place虽然"繁",但完全自主控制。三种布局方式,没有哪种最好,哪种不好,看实际需要求选着合适的即可。
下面,我们先过一遍place的常见属性,展示其含义及用法。
按照之前两篇文章的思路,place()先不传参,直接调用。看看会是什么效果呢?
from tkinter import (Tk, Button)
from tkinter.constants import RIGHT, LEFT, X, Y, BOTH
main_win = Tk()
main_win.title('渔道的grid布局')
width = 300
height = 300
main_win.geometry(f'{width}x{height}')
# print(main_win.keys())
apple_color = 'Crimson'
banana_color = 'Yellow'
orange_color = 'Orange'
grape_color = 'Purple'
fruit = {'apple':'Crimson', 'banana':'Yellow', 'orange':'Orange', 'grape':'Purple'}
# 默认显示效果
i = 0
for k,v in fruit.items():
bt = Button(main_win, text=k, fg='black', bg=v)
bt.place()
print(bt.place_info())
i += 1
main_win.mainloop()
和我预想的结果不一样哦!没有按钮显示出来!而且,print函数打印的place_info信息都为空字典。这样的结果也说明了place的"完全自主控制",至少需要指定起始坐标,否则place对象不知道将button放在哪儿。
x
指定 控件的在x轴的坐标值
y
指定 控件在y轴的坐标值
那么,既然要让place知道将button放在哪儿,我尝试一下,将place()指定x=0,看看是什么效果呢?
for k,v in fruit.items():
bt = Button(main_win, text=k, fg='black', bg=v)
bt.place(x=0)
print(bt.place_info())
print的打印信息如下:
从下面的效果可以发现,四个按钮是显示出来了,但是重叠在一起。原因就是起始坐标都是(0,0),所以当然会覆盖,grape button是最后显示,所以它在最上面。
从上面的结果,我们会自然的想到,调整(x,y)改变button的起始位置,应该就能将4个按钮正常的显示出来。下面,我们试试
i = 0
for k,v in fruit.items():
bt = Button(main_win, text=k, fg='black', bg=v)
bt.place(x=0, y=i*30)
print(bt.place_info())
i += 1
先看看print的打印信息:
通过将y坐标分别设置为0,30,60,90,我们可以看到,4个按钮被正常的显示出来,没有并覆盖。
ok,以上就是属性x,y的用法。控件要想显示在哪儿,就可以通过指定(x,y),即绝对坐标,来设置控件的绝对位置。
从上面的示例中我们还看到了 relx, rely, width, height,relwidth, relheight,anchor, bordermode这些属性,下面我们来一一解读这些属性。
relx
从relx的命名上,可猜测出relx表示相对坐标(PS:relative),那既然是"相对的",显然是相对父控件咯。这都是凭借自己的经验的猜测,到底是不是这样呢?relx的值应该怎么给呢?
通过tkinter的源码,我们看到对relx的说明:
relx=amount - locate anchor of this widget between 0.0 and 1.0 relative to width of master (1.0 is right edge)
从上面的注释我们可以发现,relx的作用确实是指定相对坐标,relx的取值为0~1的小数。如果relx=0,表示子控件的x方向的起始位置在父控件的最左边;如果rely=1,表示子控件的y方向的起始位置在父控件的最右边。
rely
显然,rely的作用和relx相同,只不过是表示y方向的起始位置。
好了,既然我们知道relx和rely的作用,到底代码运行的实际效果是不是和我们想象的一样呢?我们试验一下,将relx=0.5, rely=0.5,看看子控件是否将父控件的中心位置作为起始位置。
for k,v in fruit.items():
bt = Button(main_win, text=k, fg='black', bg=v)
bt.place(relx=0.5, rely=0.5)
print(bt.place_info())
print的打印信息:
从打印信息可以看出,四个按钮的relx和rely都为0.5,那么4个按钮都是将主窗口的中心位置作为起始位置,这样4个按钮应该会重叠。下面的效果显示也印证了。要想将4个按钮都显示出来而不重叠,类似x,y,设置适当的relx和rely值,使按钮不重叠即可。非常简单,这里就不再用代码演示了,可以自己试试修改relx和rely的值,然后看看效果。
width
指定 控件的宽度
height
指定 控件的高度
这两个属性的作用显而易见,我们设置相应的值来看看实际运行后的效果,是否与自己预想的一致呢?
i = 0
w = 60
h = 30
for k,v in fruit.items():
bt = Button(main_win, text=k, fg='black', bg=v)
bt.place(x=i*w, y=i*h, width=w, height=h)
print(bt.place_info())
i += 1
print的打印信息如下:
从打印信息可以看出,控件的宽和高是我们设置的值,起始位置坐标也和设置的值一致。
anchor
锚点的值可设置为:n, ne, e, se, s, sw, w, nw, or center。place的anchor属性非常有意思,下面详细介绍一下。
# -*- coding:utf-8 -*-
# @Author: Frank
# @Email: junfu0903@aliyun.com
# @Date: 2020-07-03 22:54:34
# @LastEditTime: 2020-07-03 22:56:48
# @Description:
# @FilePath: \python\pb_basic\test_tkinter\15place_anchor.py
from tkinter import (Tk, Button, Canvas)
from tkinter.constants import RIGHT, LEFT, X, Y, BOTH
main_win = Tk()
main_win.title('渔道的place布局')
width = 300
height = 300
main_win.geometry(f'{width}x{height}')
cav = Canvas(main_win, bg='blue', width=300, height=300)
cav.pack()
cav.create_line(0,150,300,150,fill='red')
cav.create_line(150,0,150,300,fill='red')
# anchor n, ne, e, se, s, sw, w, nw, or center
x=150
y=150
bt = Button(cav, text='apple', fg='black', bg='red')
bt.place(x=x, y=y, anchor='e')
print(bt.place_info())
bt = Button(cav, text='banana', fg='black', bg='yellow')
bt.place(x=x, y=y, anchor='w')
print(bt.place_info())
bt = Button(cav, text='orange', fg='black', bg='orange')
bt.place(x=x, y=y, anchor='n')
print(bt.place_info())
bt = Button(main_win, text='grape', fg='black', bg='purple')
bt.place(x=x, y=y, anchor='s')
print(bt.place_info())
bt = Button(main_win, text='pear', fg='black', bg='white')
bt.place(x=x, y=y, anchor='center')
print(bt.place_info())
main_win.mainloop()
这段示例代码就是用来说明 place的anchor属性。
第19,20行代码,画了两条交叉的直线,交点即为主窗口的中心点(150,150)。作用是为了方便演示。
第25,29,33,37,41行,创建了5个按钮,分别设置不同的颜色。
重点来了!重点来了!重点来了!
第26行,将apple按钮的起始点坐标设为(150,150),同时anchor设置为’e’; 意思就是锚点在东边,也就是右边。
锚点是指什么点?锚点即是x,y属性设置的坐标点。
锚点相对于谁 在东边?本例就是 锚点相对于按钮在东边(左边)。
所以 相对的,按钮放置在锚点的左边;
第30行,将banana按钮的起始点坐标设为(150,150),同时anchor设置为’w’;意思就是锚点在西边,也就是左边。
所以 相对的,按钮放置在锚点的右边;
第33行,将orange按钮的起始点坐标设为(150,150),同时anchor设置为’n’;意思就是锚点在北边,也就是上边。
所以 相对的,按钮放置在锚点的下边;
第37行,将grape按钮的起始点坐标设为(150,150),同时anchor设置为’s’;意思就是锚点在南边,也就是下边。
所以 相对的,按钮放置在锚点的上边;
第41行,将pear按钮的起始点坐标设为(150,150),同时anchor设置为’center’;意思就是锚点在中间。
所以 按钮的中心点为(150,150);
下面,我们来看看实际代码运行后的效果与我们分析的是否一致。
从上图中可以看到,坐标点(150,150)是主窗口的中心点。apple按钮显示在中心点的左边;banana按钮显示在中心点的右边;grape按钮显示在中心点的上边;orange按钮显示在中心点的下边;pear按钮的中心和主窗口的中心点重合。实际显示效果和我们分析的情况完全一致!完美!
综上所述,place的anchor属性的作用即是 设置控件锚点的位置。大家理解了吗?
小结:通过三篇博文对pack,grid,place的介绍,相信大家能感觉到这三种布局类的差异。pack和grid相对来说,需要控制的细节要少一些,主要由对象来完成一些默认的布局规则,同时也就降低了programmer的控制能力;place就完全由programmer自己完成布局的控制。这三种方式没有哪一种好哪一种不好,主要看使用场景,谁能更好的满足场景需求,就用谁。
好了,关于tkinter的布局就介绍到这里,如果大家发现有好玩的或不太会用的属性,可以评论下方留言,一起交流学习。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)