tkinter布局
1.pack()布局管理器
pack()
是一种简单的布局方式,按照组件添加到容器的顺序进行排列。
核心参数:
side::指定组件停靠方向,可选值:tk.TOP
(默认)、tk.BOTTOM、
tk.LEFT、
tk.RIGHT
fill: 控制组件填充方式,可选值:tk.X
(水平填充)、tk.Y
(垂直填充)、tk.BOTH
(同时填充)、None
(默认不填充)
expand: 布尔值,指定是否扩展填充额外空间(True
/False
)
anchor:组件在分配空间内的对齐方式,可选值:N
、S
、E
、W
、NE
、NW
、SE
、SW
、CENTER
padx和pady:组件外部的水平和垂直间距(像素)
ipadx和ipady:组件内部的水平和垂直间距(像素)
in_:将组件放置到指定父组件中
before 和 after :指定组件在某个组件之前或之后放置
2.place() 布局管理器
place() 允许通过精确坐标和尺寸来定位组件,适合需要绝对或相对定位的场景。
x 和 y:组件左上角的绝对坐标(像素)
relx 和 rely :组件相对于父容器宽度/高度的相对位置(0.0 到 1.0)
width 和 height :组件的固定宽度和高度(像素)
relwidth 和 relheight :组件相对于父容器宽度/高度的比例(0.0 到 1.0)
anchor:组件在指定位置的对齐方式,可选值:N
、S
、E
、W
、CENTER
等
bordermode:坐标参考模式,可选值:"inside"
(默认,相对于父容器内部)、"outside"
(相对于父容器外部)
3. grid() 布局管理器
grid()
将界面划分为行和列的网格,适合表格形式的布局。
row 和 column :组件所在的行和列(从0开始)
rowspan 和 columnspan :组件跨越的行数或列数
sticky :组件在单元格内的对齐方式,可选值:N
、S
、E
、W
或其组合(如 "nsew"
表示填充整个单元格)
padx 和 pady :组件外部的水平和垂直间距(像素)
ipadx 和 ipady :组件内部的水平和垂直间距(像素)
in_:将组件放置到指定父组件中
需要给引用图片的变量绑定上实例
核心原因:Tkinter 图片对象的 “引用陷阱”
当你在 Tkinter 中使用 ImageTk.PhotoImage
创建图片时,Python 的垃圾回收机制会在 “没有变量引用该图片” 时自动销毁它。
- 如果你不用
self
(即不把图片绑定到实例变量),create_diff_btn
方法执行完毕后,局部变量tk_button
会被销毁,图片对象失去引用,按钮就无法显示图片。 - 用
self
时,图片被绑定到实例变量(self.tk_button
),只要Wyy_Frame
实例存在,图片就会被持续引用,不会被销毁。
scrollbar = tk.Scrollbar(root)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)text = tk.Text(text_frame,width=50,height=10,wrap=tk.WORD, # 按单词换行font=("宋体", 12),bg="#f8f8f8",state=tk.DISABLED, # 只读yscrollcommand=scrollbar.set # 关联垂直滚动条
)
绑定键盘
password_Entry.bind('<Return>', lambda event: self.login())
给输入框绑定键盘上的enter键 当焦点在password_Entry上,按下enter会触发事件,event包含事件的详细信息,如按键位置等,这里用不到但必须接收
创建弹窗
# 1. 创建 Toplevel 弹窗(父窗口为当前主窗口)
self.popup = tk.Toplevel(self.root)
self.popup.title("弹窗窗口")
self.popup.geometry("300x200") # 弹窗尺寸# 2. 让弹窗置顶(可选,确保弹窗在最上层)
self.popup.transient(self.root) # 弹窗依赖主窗口存在
self.popup.grab_set() # 弹窗获取焦点,主窗口暂时不可操作(可选)# 3. 弹窗内容
tk.Label(self.popup, text="这是弹窗内容", font=("Arial", 12)).pack(pady=20)
tk.Button(
self.popup,
text="关闭弹窗",
command=self.popup.destroy # 关闭弹窗
).pack(pady=10)
# 4. 等待弹窗关闭后再继续(可选,配合 grab_set 使用)
self.root.wait_window(self.popup)
self.ai_reply_text = tk.Text(self.ai_reply_frame,font=('楷体', 12),state=tk.DISABLED,wrap=tk.WORD # 让文本在遇到单词或中文词语边界时自动换行,而不是一直横向延伸。)
grid布局为行列设置权重
for row in range(0,9): # 覆盖 row=0 到 row=7self.root.grid_rowconfigure(row, weight=2)for row in range(9,18):self.root.grid_rowconfigure(row, weight=1)# 2. 为按钮所在的列(column=3)设置权重,使其在水平方向拉伸for column in range(3):self.root.grid_columnconfigure(column, weight=1)register_button = tk.Button(self.root, width=13,height=1,bg=self.btn_color,text="注册", command=lambda: self.register())register_button.grid(row=0,column=1)login_button = tk.Button(self.root, width=13,height=1,bg=self.btn_color,text="登录",command=lambda: self.login())login_button.grid(row=1,column=1)tk.Button(self.root, text='播放音乐',width=13,height=1,bg=self.btn_color,command=self.start_music).grid(row=15,column=1)tk.Button(self.root, text='暂停播放', width=13,height=1,bg=self.btn_color,command=self.pause_music).grid(row=16,column=1)tk.Button(self.root, text='继续播放', width=13,height=1,bg=self.btn_color,command=self.unpause_music).grid(row=17,column=1)tk.Button(self.root, text='更换主题', width=13,height=1,bg=self.btn_color,command=self.switch_background).grid(row=2,column=1)