python tkinter 桌面小程序开发从入门到界面美化(主题应用推荐)
Python 3.x cxfreeze打包exe教程(一路踩坑过来的)
pack 函数,默认先使用的放到上面,然 后依次向下排,它会给我们的组件一个自认为合适的位置和大小,这是默认方式。
通俗点来讲有点类似于PS图层,一层层堆叠打包起来
from tkinter import *
root = Tk()
Button_1 = Button(root,text='Hello,World')
Button_1.pack()
root.mainloop()
设置组件的对齐方式LEFT
RIGHT
TOP
BOTTOM
from tkinter import *
root = Tk()
root.geometry('800x300+300+150') #创建一个800x300大小的GUI窗口
Button(root,text='LEFT').pack(side=LEFT) #左
Button(root,text='TOP').pack(side=TOP) #顶
Button(root,text='RIGHT').pack(side=RIGHT) #右
Button(root,text='BOTTOM').pack(side=BOTTOM)#底
root.mainloop()
设置组件是否向水平或垂直方向填充X
Y
BOTH
NONE
from tkinter import *
root = Tk()
root.geometry('800x300+300+150')
Button(root,text='LEFT').pack(side=LEFT,fill=None) #不填充(省略)
Button(root,text='TOP').pack(side=TOP,fill=X) #水平方向填充
Button(root,text='RIGHT').pack(side=RIGHT,fill=Y) #垂直方向填充
Button(root,text='BOTTOM').pack(side=BOTTOM,fill=BOTH) #水平和垂直方向填充
root.mainloop()
设置组件是否展开,当值为YES时,side选项无效。组件显示在父容器中心位置;若fill选项为BOTH,则填充父组件的剩余空间。默认为不展开YES 、NO(1、0)
from tkinter import *
root = Tk()
root.geometry('800x300+300+150')
Button(root,text='LEFT').pack(expand=YES) #随主窗体的大小变化
Button(root,text='TOP').pack(expand=YES) #随主窗体的大小变化
Button(root,text='RIGHT').pack(expand=NO) #不随主窗体的大小变化
Button(root,text='BOTTOM').pack(expand=NO) #不随主窗体的大小变化
root.mainloop()
锚选项,当可用空间大于所需求的尺寸时,决定组件被放置于容器的何处N、E、S、W、NW、NE、SW、SE、CENTER(默认值为CENTER)
表示八个方向以及中心
from tkinter import *
root = Tk()
root.geometry('800x300+300+150')
Button(root,text='NW').pack(anchor=NW) #NW
Button(root,text='N').pack(anchor=N) #N
Button(root,text='NE').pack(anchor=NE) #NE
Button(root,text='W').pack(anchor=W) #W
Button(root,text='C').pack(anchor=CENTER) #CENTER
Button(root,text='E').pack(anchor=E) #E
Button(root,text='NS').pack(anchor=SW) #SW
Button(root,text='S').pack(anchor=S) #S
Button(root,text='SE').pack(anchor=SE) #SE
root.mainloop()
设置x方向(或者y方向)内部间隙(子组件之间的间隔),可设置数值,默认是0,非负整数,单位为像素
from tkinter import *
root = Tk()
root.geometry('800x300+300+150')
Button(root,text='A').pack(ipadx=0) #
Button(root,text='B').pack(ipadx=2) #
Button(root,text='C').pack(ipadx=4) #
Button(root,text='D').pack(ipadx=6) #
Button(root,text='F').pack(ipady=0) #
Button(root,text='G').pack(ipady=2) #
Button(root,text='H').pack(ipady=4) #
Button(root,text='I').pack(ipady=6) #
root.mainloop()
设置x方向(或者y方向)外部间隙(与之并列的组件之间的间隔),可设置数值,默认是0,非负整数,单位为像素
理解组件外部间隙,一个很好的例子如下
from tkinter import *
root = Tk()
root.geometry('800x300+300+150')
# padx
Button(root, text='Left').pack(side=LEFT)
Button(root, text='Center').pack(side=LEFT)
Button(root, text='Right').pack(side=LEFT,padx=10)
# pady
Button(root,text='G').pack()
Button(root,text='H').pack()
Button(root,text='I').pack(pady=6)
root.mainloop()
使用组件实例对象调用:
函数名 | 描述 |
---|---|
pack_slaves() | 以列表方式返回本组件的所有子组件对象。 |
pack_configure(option=value) | 给pack布局管理器设置属性,使用属性(option)= 取值(value)方式设置 |
propagate(boolean) | 设置为True表示父组件的几何大小由子组件决定(默认值),反之则无关。 |
pack_info() | 返回pack提供的选项所对应得值。 |
pack_forget() | Unpack组件,将组件隐藏并且忽略原有设置,对象依旧存在,可以用pack(option, …),将其显示。 |
location(x, y) | x, y为以像素为单位的点,函数返回此点是否在单元格中,在哪个单元格中。返回单元格行列坐标,(-1, -1)表示不在其中 |
size() | 返回组件所包含的单元格,揭示组件大小。 |
答案引用CSDN一位博主的一篇例文,效果如下:
版权声明:本文为CSDN博主「编程之路从0到1」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yingshukun/article/details/53983812
from tkinter import * #注意模块导入方式,否则代码会有差别
class App:
def __init__(self, master):
#使用Frame增加一层容器
fm1 = Frame(master)
#Button是一种按钮组件,与Label类似,只是多出了响应点击的功能
Button(fm1, text='Top').pack(side=TOP, anchor=W, fill=X, expand=YES)
Button(fm1, text='Center').pack(side=TOP, anchor=W, fill=X, expand=YES)
Button(fm1, text='Bottom').pack(side=TOP, anchor=W, fill=X, expand=YES)
fm1.pack(side=LEFT, fill=BOTH, expand=YES)
fm2 = Frame(master)
Button(fm2, text='Left').pack(side=LEFT)
Button(fm2, text='This is the Center button').pack(side=LEFT)
Button(fm2, text='Right').pack(side=LEFT)
fm2.pack(side=LEFT, padx=10)
root = Tk()
root.title("Pack - Example")
display = App(root)
root.mainloop()
Pack 作为首选的布局管理方式,其运作方式并不是特别易于理解,已经由 Pack 布局完成的设计也很难做出改变。Grid 布局在1996年作为另一种可供选择的布局方式被引入,Grid 布局方式易学易用,但似乎大家还是习惯用 Pack。
Python TkinterGrid布局管理器详解
官方生硬的文字就不写了,可以看作是网格布局,是最被推荐使用的布局。
GUI界面大多都是矩形的一个窗口,那么我们可以将其分为几行几列的网格,然后根据行列索引号来放置组件
用grid 布局时,需要指定两个参数,分别用row 表示行,column 表示列
注意:row
和 column
的序号都从0
开始
注意:不要试图在一个主窗口中混合使用pack和grid
from tkinter import *
root=Tk()
root.title('Grid Example')
root.geometry('800x300+300+150')
#标签控件,显示文本和位图
Label(root,text="First").grid(row=0) #第1行
Label(root,text="Second").grid(row=1)#第2行
#输入控件
Entry(root).grid(row=0,column=1) #第1行,第1列
Entry(root).grid(row=1,column=1) #第2行,第1列
mainloop()
option | 解释 |
---|---|
column | 插件布放的列数值,从0开始。默认值为0 |
columnspan | 正常情况下,一个插件只占一个单元 。但是,你可以通过设置 columnspan 来合并一行中的多个邻近 单元 ,并用此 单元 放置本插件。比如, w.grid(row=0, column=2, columnspan=3) ,这会把插件 w 布置在 将第0行的2,3,4列合并后的 单元 中。 |
in_ | 用 in_=w2 可以将 w 登记为 w2 的child插件。 w2 必须是 w 创建时指定parent插件的child插件。 |
ipadx | x方向的内部填充。在插件内部,左右方向各填充指定长度的空间。 |
ipady | y方向的内部填充。在插件内部,上下方向各填充指定长度的空间。 |
padx | x方向的外部填充。在插件外部,左右方向各填充指定长度的空间。 |
pady | y方向的内部填充。在插件内部,上下方向各填充指定长度的空间。 |
row | 插件布放的行数值,从0开始。默认值 为 未布放行 的下一个数值。 |
rowspan | 正常情况下,一个插件只占一个单元 。但是,你可以通过设置 rowspan 来合并一列中的多个邻近 单元 ,并用此 单元 放置本插件。比如, w.grid(row=3, column=2, rowspan=4, columnspan=3) ,这会把插件 w 布置在 合并了20个 单元 的区域中,也就是3-6行和2-6列。 |
sticky | 这个参数用来确定:在插件正常尺寸下,如何分配 单元 中多余的空间。具体如下。 |
sticky=tk.NE
(靠右上方),sticky=tk.SE
(靠右下方),sticky=tk.SW
(靠左下方),sticky=tk.NW
(靠左上方),可以将插件布置在 单元 的某个角落。sticky=tk.N
(靠上方),sticky=tk.E
(靠右方),sticky=tk.S
(靠下方),sticky=tk.W
(靠左方),可以将插件布置在 单元 的某个方向上。sticky=tk.N+tk.S
,在垂直方向上延伸插件,并保持水平居中。sticky=tk.E+tk.W
,在水平方向上延伸插件,并保持垂直居中。sticky=tk.N+tk.E+tk.W
,在水平和垂直方向上延伸插件,填满 单元 。sticky=tk.N+tk.S+tk.W
,在垂直方向上延伸插件,并靠左布放。from tkinter import *
root=Tk()
root.title('Grid Example')
root.geometry('800x300+300+150')
#标签控件,显示文本和位图
Label(root,text="First").grid(row=0,sticky=E) #第1行,靠右
Label(root,text="Second").grid(row=1,sticky=W)#第2行,靠左
#输入控件
Entry(root).grid(row=0,column=1) #第1行,第1列
Entry(root).grid(row=1,column=1) #第2行,第1列
mainloop()
from tkinter import *
root=Tk()
root.title('Grid Example')
root.geometry('800x300+300+150')
var=IntVar()
#标签控件,显示文本和位图
Label(root,text="First").grid(row=0,sticky=E) #第1行,靠右
Label(root,text="Second").grid(row=1,sticky=W)#第2行,靠左
#输入控件
Entry(root).grid(row=0,column=1) #第1行,第1列
Entry(root).grid(row=1,column=1) #第2行,第1列
#检查控件
button=Checkbutton(root,text="Precerve aspect",variable=var)
button.grid(sticky=W)
mainloop()
from tkinter import *
root=Tk()
root.title('Grid Example')
root.geometry('800x300+300+150')
var=IntVar()
#标签控件,显示文本和位图
Label(root,text="First").grid(row=0,sticky=E) #第1行,靠右
Label(root,text="Second").grid(row=1,sticky=W)#第2行,靠左
#输入控件
Entry(root).grid(row=0,column=1) #第1行,第1列
Entry(root).grid(row=1,column=1) #第2行,第1列
#检查控件
button=Checkbutton(root,text="Precerve aspect",variable=var)
button.grid(columnspan=2,sticky=W)
mainloop()
最简单最灵活的一种布局,使用组件坐标来放置组件的位置。但是不太推荐使用,在不同分辨率下,界面往往有较大差异
place 布局管理器可以通过坐标精确控制组件的位置
适用于一些布局更加灵活的场景
属性名 | 属性简析 | 取值 | 取值说明 |
---|---|---|---|
anchor | 锚选项,同pack布局 | 默认值为 NW | 同pack布局 |
x、y | 组件左上角的x、y坐标 | 整数,默认值0 | 绝对位置坐标,单位像素 |
relx、rely | 组件相对于父容器的x、y坐标 | 0~1之间浮点数 | 相对位置,0.0表示左边缘(或上边缘),1.0表示右边缘(或下边缘) |
width、height | 组件的宽度、高度 | 非负整数 | 单位像素 |
relwidth、relheight | 组件相对于父容器的宽度、高度 | 0~1之间浮点数 | 与relx(rely)取值相似 |
案例参考https://blog.csdn.net/aa1049372051/article/details/51887144
from tkinter import *
root = Tk()
root.title('使用绝对坐标将组件放到指定的位置')
root.geometry('800x300+300+150')
lb = Label(root, text='hello Place')
# lb.place(relx = 1,rely = 0.5,anchor = CENTER)
# 使用绝对坐标将Label放置到(0,0)位置上
lb.place(x=0, y=0, anchor=NW)
root.mainloop()
# x,y指定组件放置的绝对位置
from tkinter import *
root = Tk()
root.title('使用相对坐标放置组件位置')
root.geometry('800x300+300+150')
lb = Label(root, text='hello Place')
# lb.place(relx = 1,rely = 0.5,anchor = CENTER)
# 使用相对坐标(0.5,0.5)将Label放置到(0.5*sx,0.5.sy)位置上
lb.place(relx=0.5, rely=0.5, anchor=CENTER)
root.mainloop()
# relx,rely指定组件放置的绝对位置,范围为(0-1.0)
from tkinter import *
root = Tk()
root.title('使用place同时指定多个组件')
root.geometry('800x300+300+150')
lb = Label(root, text='hello Place')
# lb.place(relx = 1,rely = 0.5,anchor = CENTER)
# 使用相对坐标(0.5,0.5)将Label放置到(0.5*sx,0.5.sy)位置上
v = IntVar()
for i in range(5):
Radiobutton(
root,
text='Radio' + str(i),
variable=v,
value=i
).place(x=80 * i, anchor=NW)
root.mainloop()
# 使用place来指定各个Radiobutton的位置
from tkinter import *
root = Tk()
root.title('同时使用相对和绝对坐标')
root.geometry('800x300+300+150')
lb1 = Label(root, text='hello Place', fg='green')
lb2 = Label(root, text='hello Place', fg='red')
# 先设置相对坐标为(0.5,0.5),再使用(-200,-200)将坐标作偏移(-200,-200)
lb1.place(relx=0.5, rely=0.5, anchor=CENTER, x=-200, y=-200)
# 先设置相对坐标为(0.5,0.5),再使用(-300,-300)将坐标作偏移(-300,-300)
lb2.place(relx=0.5, rely=0.5, anchor=CENTER, x=-300, y=-300)
root.mainloop()
# 同时使用相对和绝对坐标时,相对坐标优先操作,然后是在这个相对坐标的基础上进行偏移
使用in属性来指定放置到的容器是那一个
from tkinter import *
root = Tk()
root.title('使用in来指定放置的容器')
root.geometry('800x300+300+150')
lb1 = Label(root, text='hello Place Label', fg='green')
bt1 = Button(root, text='hello Place Button', fg='red')
# 创建一个Label
lb1.place(relx=0.5, rely=0.5, anchor=CENTER)
# 在root同创建一个Button,目的是与bt1相比较
bt2 = Button(root, text='button in root', fg='yellow')
bt2.place(anchor=W)
# 在Label中创建一个Button
bt1.place(in_=lb1, anchor=W)
root.mainloop()
# 注意bt2放置的位置是在root的(0,0)处,而button1放置的位置是在lb1的(0,0)处,原因是由于bt1使用了in来指定放置的窗口为lb1
使用in属性来指定放置到的容器是那一个,仅能是其master
from tkinter import *
root = Tk()
root.title('深入in用法')
root.geometry('800x300+300+150')
# 创建两个Frame用作容器
fm1 = Frame(root, bg='red', width=40, height=40)
fm2 = Frame(root, bg='blue', width=40, height=40)
# 再在fm1中创建一个fm3
fm3 = Frame(fm1, bg='yellow', width=20, height=20)
# 创建一个Label,它的master为fm1
lb1 = Label(fm1, text='hello Place', fg='green')
lb1.place(in_=fm1, relx=0.5, rely=0.5, anchor=CENTER)
# 创建一个Button,它的master为fm1
bt1 = Button(fm1, text='hello Place', fg='red')
# 将bt1放置到fm2中,程序报错
# 去掉下面这条语句就可以使用了,可以看到lb1已经正确的放置到fm1的中心位置了
# bt1.place(in_ = fm2,anchor = W)
# 将上面的语句改为下面,即将bt1放置到其fm1的子组件fm3中,这样也是可以的
bt1.place(in_=fm3, anchor=W)
fm1.pack()
fm2.pack()
fm3.pack()
root.mainloop()
# in不是可以随意指定放置的组件的,如果使用in这个参数这个组件必需满足:是其父容器或父容器的子组件
最后使用两个place方法来动态改变两个Frame的大小
from tkinter import *
root = Tk()
root.title('事件与Place结合使用')
root.geometry('800x300+300+150')
split = 0.5
fm1 = Frame(root,bg = 'red')
fm2 = Frame(root,bg = 'blue')
# 单击fm1时增大它的占有区域0.1
def incFm1(event):
global split
if split < 1:
split += 0.1
fm1.place(rely = 0,relheight = split,relwidth = 1)
fm2.place(rely = split,relheight = 1 - split,relwidth = 1)
# 单击fm2时增大它的占有区域0.1
def incFm2(event):
global split
if split > 0:
split -= 0.1
fm1.place(rely = 0,relheight = split,relwidth = 1)
fm2.place(rely = split,relheight = 1 - split,relwidth = 1)
# 这两语句要使用,不然开始看不到两个frame,也就没法点击它们了
fm1.place(rely = 0,relheight = split,relwidth = 1)
fm2.place(rely = split,relheight = 1 - split,relwidth = 1)
# 绑定单击事件
fm1.bind('' ,incFm1)
fm2.bind('' ,incFm2)
root.mainloop()
# 为SplitWindow的原型了,再改动一下就可以实现一个SplitWindow了。
以上就是布局管理的总结和学习,文中有些内容摘自平台已注明出处,图片均为原创,排版纯按照个人喜好来排布,鄙人稍微有些强迫症,一个好的排版可以更快的吸收,如果有任何问题请下方留言,好看收藏+关系,谢谢