当前位置: 首页 > news >正文

tkinter 第三章 窗口控件配置管理器

第三章 窗口控件配置管理器

Layout Manager在设计GUI程序时,可以使用三种方法包装和定位各组件在容器或窗口内的位置,这三个方法又称为窗口控件配置管理员 (Widget Layout Manager)。

初级布局管理

当我们在开发一个 GUI 程序的时候,布局管理发挥着非常重要的作用,它指的是通过管理控件在窗口中的位置(排版),从而实现对窗口和控件布局的目的。

Tkinter 提供了一系列布局管理的方法和容器控件,同一个额布局,可以用不同的方法完成。

Tkinter 提供了三种常用的布局管理器,分别是 pack()、grid() 以及 place(),如下表所示:

方法说明
pack()按照控件的添加顺序其进行排列,遗憾的是此方法灵活性较差
grid()以行和列(网格)形式对控件进行排列,此种方法使用起来较为灵活
place()可以指定组件大小以及摆放位置,三个方法中最为灵活的布局方法

上述三种方法适用于 Tkinter 中的所有控件。

尽量优先选择pack或grid布局,place可以精确设置控件位置,但当窗口组件过多时比较繁琐。

pack()

pack() 是一种较为简单的布局方法,在不使用任何参数的情况下,它会将控件以添加时的先后顺序,自上而下,一行一行的进行排列,并且默认居中显示。

pack( )方法的语法格式如下。

pack(option,...)

options参数可以是side、fill、padx/pady、ipadx/ipady、anchor。

选项描述
side定义了组件应该放置在哪个位置,可以是LEFT、RIGHT、TOP、BOTTOM或CENTER。默认值是TOP。
fill定义了在分配额外空间时如何填充组件。可以是X(水平)、Y(垂直)、BOTH(水平和垂直)或NONE(不填充)。默认值是X。
padx/pady定义组件周围的空间量(以像素为单位)。padx是水平空间,pady是垂直空间。这些值可以是整数或百分比字符串。
ipadx/ipady定义组件内部的空间量(以像素为单位),用于增加组件内部元素之间的空间。ipadx是水平内部空间,ipady是垂直内部空间。这些值可以是整数或百分比字符串。
anchor定义组件在指定位置的对齐方式。可以使用位置常数如NORTHWEST等或者边缘常量如W(西)、E(东)等来表示。默认值是NW(左上角)。
expand是否可扩展窗口,参数值为 True(扩展)或者 False(不扩展),默认为 False,若设置为 True,则控件的位置始终位于窗口的中央位置

示例:

importtkinterastk# 创建主窗口root=tk.Tk()root.title("Pack 示例")root.geometry("300x200")# 创建并放置标签控件label1=tk.Label(root,text="标签 1",bg="lightblue")label1.pack(pady=10)# 垂直间距label2=tk.Label(root,text="标签 2",bg="lightgreen")label2.pack(pady=10)# 垂直间距# 创建按钮控件button=tk.Button(root,text="点击我")button.pack(pady=10)# 垂直间距# 创建另一个标签控件label3=tk.Label(root,text="标签 3",bg="lightcoral")label3.pack(pady=10)# 垂直间距# 运行主循环root.mainloop()

运行结果:

side

当窗口中有多个组件时,使用pack( )方法可以让组件由上往下排列显示,也是系统的默认设置。

使用pack( )方法时,也可以增加side参数设置组件的排列方式,此参数的取值如下。

  • TOP:这是默认值,由上往下排列。
  • BOTTOM:由下往上排列。
  • LEFT:由左往右排列。
  • RIGHT:由右往左排列。

示例:pack参数side使用示例

importtkinterastk# 创建主窗口root=tk.Tk()root.title("Pack Side 示例")root.geometry("300x200")# 创建标签和按钮控件label1=tk.Label(root,text="上方",bg="lightblue")label1.pack(side=tk.TOP,padx=10,pady=10)label2=tk.Label(root,text="左侧",bg="lightgreen")label2.pack(side=tk.LEFT,padx=10,pady=10)label3=tk.Label(root,text="右侧",bg="lightcoral")label3.pack(side=tk.RIGHT,padx=10,pady=10)label4=tk.Label(root,text="底部",bg="lightyellow")label4.pack(side=tk.BOTTOM,padx=10,pady=10)# 运行主循环root.mainloop()

运行结果:

fill

示例:pack参数fill示例

importtkinterastk# 创建主窗口root=tk.Tk()root.title("Tkinter Pack Fill 示例")root.geometry("400x300")# 创建并配置标签label1=tk.Label(root,text="标签 1",bg="lightblue")label1.pack(side=tk.TOP,fill=tk.X,pady=10)# 创建第二个标签label2=tk.Label(root,text="标签 2",bg="lightgreen")label2.pack(side=tk.TOP,fill=tk.X,pady=10)# 创建第三个标签label3=tk.Label(root,text="标签 3",bg="lightcoral")label3.pack(side=tk.TOP,fill=tk.X,pady=10)# 创建按钮,设置填充属性button=tk.Button(root,text="点击我")button.pack(side=tk.BOTTOM,fill=tk.BOTH,pady=10)# 运行主循环root.mainloop()

运行结果:

padx/pady,ipadx/ipady

示例:padx 和 pady,ipadx 和 ipady使用

importtkinterastk# 创建主窗口实例root=tk.Tk()root.geometry('300x200')# 设置窗口大小root.title('Pack 参数示例')# 设置窗口标题# 创建按钮实例button=tk.Button(root,text='点击我',command=lambda:print('按钮被点击了'))# 使用pack布局管理器设置按钮的位置和大小# padx 和 pady 用于设置按钮边缘和外部容器之间的空间大小# ipadx 和 ipady 用于设置按钮内部的空间大小(如果按钮是可点击的)button.pack(padx=20,pady=10,ipadx=50,ipady=3)# 设置水平和垂直填充以及内部填充大小# 运行主循环,等待窗口关闭事件root.mainloop()

运行结果:

anchor

示例:pack函数anchor参数

importtkinterastk# 创建主窗口root=tk.Tk()root.title("Pack Anchor 示例")root.geometry("300x200")# 创建并放置标签控件label_north=tk.Label(root,text="北",bg="lightblue",width=20)label_north.pack(anchor='n',pady=5)label_south=tk.Label(root,text="南",bg="lightgreen",width=20)label_south.pack(anchor='s',pady=5)label_east=tk.Label(root,text="东",bg="lightcoral",width=20)label_east.pack(anchor='e',pady=5)label_west=tk.Label(root,text="西",bg="lightyellow",width=20)label_west.pack(anchor='w',pady=5)label_center=tk.Label(root,text="中心",bg="lightgray",width=20)label_center.pack(anchor='center',pady=5)# 运行主循环root.mainloop()

运行结果:

expand

expand参数可设定Widget控件是否填满额外的父容器空间,默认是False(或是0),表示不填满,如果是True(或是1)表示填满。

示例:

fromtkinterimport*root=Tk()root.title("expand")#窗口标题Label(root,text='1 ',bg='red',fg='white',font='Times 20 bold').pack(side=LEFT,fill=Y)Label(root,text='2 ',bg='green',fg='white',font='Arial 20 bold italic').pack(side=LEFT,fill=BOTH,expand=True)Label(root,text='3 ',bg='blue',fg='white',font='Times 20 bold').pack(side=LEFT,fill=Y)root.mainloop()

运行结果:

grid()

grid() 函数是一种基于网格式的布局管理方法,相当于把窗口看成了一张由行和列组成的表格。

当使用该 grid 函数进行布局的时,表格内的每个单元格都可以放置一个控件,从而实现对界面的布局管理。

  • 注:这里的所说的“表格”是虚拟出来,窗体并不会因为使用了 gird() 函数,而增加一个表格。
  • grid()布局方法不能与 pack()混合在一起使用。

总结:使用 grid 函数布局的时,其实就是为各个控件指定行号、列号的过程,不需要为每个单元格指定大小,grid 会为每个单元格自动设置一个适合的尺寸。

grid()格式:

grid(options,)

grid() 函数的常用参数 option 如下所示:

属性说明
row控件位于表格中的第几行,窗体最上面为起始行,默认为第 0 行
column控件位于表格中的第几列,窗体最左边的为起始列,默认为第 0 列
rowspan控件实例所跨的行数,默认为 1 行,通过该参数可以合并一列中多个领近单元格。
columnsapn控件实例所跨的列数,默认为 1 列,通过该参数可以合并一行中多个领近单元格。
ipadx,ipady用于控制内边距,在单元格内部,左右、上下方向上填充指定大小的空间。
padx,pady用于控制外边距,在单元格外部,左右、上下方向上填充指定大小的空间。
sticky该属性用来设置控件位于单元格哪个方位上,参数值和 anchor 相同,若不设置该参数则控件在单元格内居中

grid() 方法相比 pack() 方法来说要更加灵活,以网格的方式对组件进行布局管理,让整个布局显得非常简洁、优雅。

注意:在一个程序中不能同时使用 pack() 和 grid() 方法,这两个方法只能二选一,否则程序会运行错误。

示例:

fromtkinterimport*#主窗口win=Tk()win.config(bg='white')win.title("hello")win.geometry('500x350+300+300')#在窗口内创建按钮,以表格的形式依次排列foriinrange(10):forjinrange(10):Button(win,text=" ("+str(i)+","+str(j)+")",bg='#D1EEEE').grid(row=i,column=j)#开始窗口的事件循环win.mainloop()

运行结果:

rowspan/columnspan

示例:使用grid函数中rowspancolumnspan参数

importtkinterastk# 创建主窗口root=tk.Tk()root.title("Grid rowspan 和 columnspan 示例")root.geometry("300x200")# 创建标签label1=tk.Label(root,text="标签 1",bg="lightblue",width=20)label1.grid(row=0,column=0)label2=tk.Label(root,text="标签 2",bg="lightgreen",width=20)label2.grid(row=0,column=1)label3=tk.Label(root,text="标签 3",bg="lightcoral",width=20)label3.grid(row=1,column=0,columnspan=2)# 跨越两列label4=tk.Label(root,text="标签 4",bg="lightyellow",width=20)label4.grid(row=2,column=0)label5=tk.Label(root,text="标签 5",bg="lightgray",width=20)label5.grid(row=2,column=1,rowspan=2)# 跨越两行label6=tk.Label(root,text="标签 6",bg="lightpink",width=20)label6.grid(row=3,column=0)# 运行主循环root.mainloop()

运行结果:

sticky

功能类似anchor,但是只可以设定N/S/W/E,即上/下/左/右对齐。

原则上相同column的Widget控件,如果宽度不同时,grid( )方法会保留最宽的控件当作基准,这时比较短的控件会居中对齐。

示例:

importtkinterastk# 创建主窗口root=tk.Tk()root.title("Grid Sticky 示例")root.geometry("300x200")# 创建并放置标签控件label1=tk.Label(root,text="左上",bg="lightblue",width=10)label1.grid(row=0,column=0,sticky="nw",padx=5,pady=5)label2=tk.Label(root,text="右上",bg="lightgreen",width=10)label2.grid(row=0,column=1,sticky="ne",padx=5,pady=5)label3=tk.Label(root,text="左下",bg="lightcoral",width=10)label3.grid(row=1,column=0,sticky="sw",padx=5,pady=5)label4=tk.Label(root,text="右下",bg="lightyellow",width=10)label4.grid(row=1,column=1,sticky="se",padx=5,pady=5)label5=tk.Label(root,text="中心",bg="lightgray",width=10)label5.grid(row=1,column=0,columnspan=2,sticky="nsew",padx=5,pady=5)# 设置行和列的权重,以便自动扩展root.grid_rowconfigure(1,weight=1)root.grid_columnconfigure(0,weight=1)root.grid_columnconfigure(1,weight=1)# 运行主循环root.mainloop()

运行结果:

place()

与前两种布局方法相比,采用 place() 方法进行布局管理要更加精细化,通过 place() 布局管理器可以直接指定控件在窗体内的绝对位置,或者相对于其他控件定位的相对位置。

place 布局管理器的常用属性:

属性说明
anchor定义控件在窗体内的方位,参数值N/NE/E/SE/S/SW/W/NW 或 CENTER,默认值是 NW
bordermode定义控件的坐标是否要考虑边界的宽度,参数值为 OUTSIDE(排除边界) 或 INSIDE(包含边界),默认值 INSIDE。
x/y定义控件在根窗体中水平和垂直方向上的起始绝对位置
relx/rely1. 定义控件相对于根窗口(或其他控件)在水平和垂直方向上的相对位置(即位移比例),取值范围再 0.0~1.0 之间 2. 可设置 in_ 参数项,相对于某个其他控件的位置
height/width控件自身的高度和宽度(单位为像素)
relheight/relwidth控件高度和宽度相对于根窗体高度和宽度的比例,取值也在 0.0~1.0 之间

relx 和 rely 参数指定的是控件相对于父组件的位置

relwidth 和 relheight 参数是指定控件相对于父组件的尺寸大小

注意:这里父组件指的是当前可操作控件的上层组件,比如在没有使用容器控件(frame)的窗体中,控件的父组件就是主窗口本身。

示例:

importtkinterastk# 创建主窗口root=tk.Tk()root.title("Place 示例")root.geometry("400x300")# 创建标签控件label1=tk.Label(root,text="标签 1",bg="lightblue")label1.place(x=50,y=50)# 指定坐标 (50, 50)label2=tk.Label(root,text="标签 2",bg="lightgreen")label2.place(relx=0.5,rely=0.5,anchor='center')# 相对中心位置label3=tk.Label(root,text="标签 3",bg="lightcoral")label3.place(x=200,y=200,width=100,height=50)# 指定坐标和大小label4=tk.Label(root,text="标签 4",bg="lightyellow")label4.place(relx=0.8,rely=0.2,anchor='ne')# 右上角# 运行主循环root.mainloop()

运行结果:

http://www.jsqmd.com/news/728872/

相关文章:

  • 从‘空间平滑’到‘特征向量重构’:深入浅出图解I-MUSIC算法如何‘无损’解相干
  • 全网视频音乐搜索播放器,支持在线播放与预览
  • FigmaCN中文插件终极指南:5种用户场景下的完美汉化解决方案
  • R语言数据报告革命:Tidyverse 2.0+Quarto+GitHub Actions实现零干预月度成本报表(附可审计代码模板)
  • LLM偏见审计工具链落地难?R-biasDetect v2.4.1正式版限时开放下载(仅限前500名认证开发者)
  • OpenClaw智能体监控:零侵入实时仪表盘Mission Control部署指南
  • 你的分类数据可视化还停在箱线图?试试用Python山脊图做深入洞察(避坑重叠与标签问题)
  • IT内幕11:海思工程师薪资揭秘:芯片岗真的年包 50W+?
  • Tidyverse 2.0正式发布后,92%的数据科学家还没掌握的5个自动化报告新范式:从手动渲染到CI/CD集成
  • AISystem:鸿蒙游戏中的 AI 行为驱动
  • Android开发与ARM Cortex-A8核心深度适配及优化实践
  • 穿透宿主机内核:QNAP Virtualization Station 硬件直通解析
  • 2026年材料科学论文降AI工具推荐:材料工程研究答辩前亲测3款对比方案
  • 终极指南:5步搭建免费开源Sunshine游戏串流服务器
  • LLM智能体在时间序列预测中的创新应用
  • 南京奢侈品回收选品推荐:南京,徐州名车典当,名车抵押,和田玉回收,房产抵押,翡翠回收,铂金回收,优选指南! - 优质品牌商家
  • 如果你正在做采购管理,这篇文章建议你认真看完(关于CPPM)
  • 桥梁拉索索力异常识别【附代码】
  • CubeMX配置STM32串口DMA后,为什么连续调用HAL_UART_Transmit_DMA会失败?一个调试案例复盘
  • 【Writeup】pwnable.kr--blackjack
  • 企业微信会话存档 API 开发实战:合规存档与数据检索全流程
  • 数据流加速器基准测试:Graphcore IPU、Cerebras CS-2与SambaNova SN30对比
  • 在Windows上直接安装安卓应用:APK Installer的五大高效解决方案
  • 【Laravel 12+ AI工程化落地指南】:从零集成LangChain、LlamaIndex与OpenAI,3小时构建生产级智能客服系统
  • 【云藏山鹰代数信息系统】浅析气质砥砺学研究范式
  • 0 代码自动化测试:RF 框架实现企业级 UI 自动化测试
  • 阿里云OSS Java SDK安全升级指南:从硬编码AK到环境变量,我这样管理敏感配置
  • Dify 2026边缘节点部署倒计时:2026年Q3起,未通过Dify Edge Compliance Check的节点将自动退出联邦推理网络
  • 【独家首发】Dify 2026文档解析精度优化内参:基于217万真实业务PDF的误差热力图+12个高危Layout Pattern规避指南
  • TV Bro电视浏览器:智能电视上网的终极解决方案