tkinter布局

1.pack()布局管理器

pack() 是一种简单的布局方式,按照组件添加到容器的顺序进行排列。

核心参数

side::指定组件停靠方向,可选值:tk.TOP(默认)、tk.BOTTOMtk.LEFTtk.RIGHT

fill: 控制组件填充方式,可选值:tk.X(水平填充)、tk.Y(垂直填充)、tk.BOTH(同时填充)、None(默认不填充)

expand: 布尔值,指定是否扩展填充额外空间(True/False

anchor:组件在分配空间内的对齐方式,可选值:NSEWNENWSESWCENTER

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:组件在指定位置的对齐方式,可选值:NSEWCENTER

bordermode:坐标参考模式,可选值:"inside"(默认,相对于父容器内部)、"outside"(相对于父容器外部)

3. grid() 布局管理器

grid() 将界面划分为行和列的网格,适合表格形式的布局。

row 和 column :组件所在的行和列(从0开始)

rowspan 和 columnspan :组件跨越的行数或列数

sticky :组件在单元格内的对齐方式,可选值:NSEW 或其组合(如 "nsew" 表示填充整个单元格)

padx 和 pady :组件外部的水平和垂直间距(像素)

ipadx 和 ipady :组件内部的水平和垂直间距(像素)

in_:将组件放置到指定父组件中

需要给引用图片的变量绑定上实例

核心原因:Tkinter 图片对象的 "引用陷阱"

当你在 Tkinter 中使用 ImageTk.PhotoImage 创建图片时,Python 的垃圾回收机制会在 "没有变量引用该图片" 时自动销毁它。

  • 如果你不用 self(即不把图片绑定到实例变量),create_diff_btn 方法执行完毕后,局部变量 tk_button 会被销毁,图片对象失去引用,按钮就无法显示图片。
  • self 时,图片被绑定到实例变量(self.tk_button),只要 Wyy_Frame 实例存在,图片就会被持续引用,不会被销毁。
python 复制代码
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  # 关联垂直滚动条
)

绑定键盘

python 复制代码
password_Entry.bind('<Return>', lambda event: self.login())

给输入框绑定键盘上的enter键 当焦点在password_Entry上,按下enter会触发事件,event包含事件的详细信息,如按键位置等,这里用不到但必须接收

创建弹窗

python 复制代码
# 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)
python 复制代码
self.ai_reply_text = tk.Text(
                self.ai_reply_frame,
                font=('楷体', 12),
                state=tk.DISABLED,
                wrap=tk.WORD  # 让文本在遇到单词或中文词语边界时自动换行,而不是一直横向延伸。
            )

grid布局为行列设置权重

python 复制代码
        for row in range(0,9):  # 覆盖 row=0 到 row=7
            self.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)
可以简单理解,权重大分到的面积就大