为何添加按钮后Tkinter Frame会自动调整大小?
Tkinter Frame添加按钮后尺寸被压缩的问题解决
问题描述
编写了一段创建带Frame的Tkinter窗口代码,未添加按钮时Frame尺寸符合预期。但取消注释添加按钮的代码后,Frame会被调整为按钮的大小,希望Frame保持原有尺寸,不随按钮添加而改变。原代码如下:
import tkinter as tk class FrameClass: def __init__(self, root, hl_color, hl_thickness, height, width): self.root = root self.hl_color = hl_color self.hl_thickness = hl_thickness self.height = height self.width = width def make_frame(self): frame = tk.Frame(self.root, highlightbackground=self.hl_color, highlightthickness=self.hl_thickness, width=self.width, height=self.height) padx, pady = self.width/10, self.height/10 frame.grid(pady=padx, padx=pady) return frame class ButtonFunction: def __init__(self): print("click") class ButtonClass: def __init__(self, root, text, bg, padx, pady, relief): self.root = root self.text = text self.bg = bg self.padx = padx self.pady = pady self.relief = relief def button_function(self): ButtonFunction() def make_button(self): button = tk.Button(self.root, text=self.text, bg=self.bg, padx=self.padx, pady=self.pady, relief=self.relief, command=self.button_function) button.grid() class Main: def __init__(self): self.root = tk.Tk() self.root.title("Application") self.root.geometry("400x300") self.root.columnconfigure(0, weight=1) self.root.rowconfigure(0, weight=1) def application(self): F = FrameClass(self.root, "BLACK", 5, 400*0.9, 300*0.9) frame = F.make_frame() # button_color, padx, pady, relief = "GREY", 25, 10, tk.GROOVE # B1 = ButtonClass(frame, "Button 1", button_color, padx, pady, relief) # B1.make_button() self.root.mainloop() if __name__ == "__main__": M = Main() M.application()
原因分析
Tkinter中使用grid布局时,容器(比如这里的Frame)默认会自动调整自身尺寸以适应子组件的大小,哪怕你给Frame设置了width和height属性,只要添加了子组件,Frame就会忽略这些预设尺寸,优先匹配子元素的大小。这就是添加按钮后Frame被压缩成按钮大小的核心原因。
解决方案
最直接的解决方法是给Frame调用grid_propagate(False)方法,关闭它的自动尺寸调整功能,强制保持你设置的宽高。
修改后的代码如下(标注了关键修改点):
import tkinter as tk class FrameClass: def __init__(self, root, hl_color, hl_thickness, height, width): self.root = root self.hl_color = hl_color self.hl_thickness = hl_thickness self.height = height self.width = width def make_frame(self): frame = tk.Frame(self.root, highlightbackground=self.hl_color, highlightthickness=self.hl_thickness, width=self.width, height=self.height) padx, pady = self.width/10, self.height/10 frame.grid(pady=padx, padx=pady) # 新增:关闭Frame的自动尺寸调整 frame.grid_propagate(False) return frame class ButtonFunction: def __init__(self): print("click") class ButtonClass: def __init__(self, root, text, bg, padx, pady, relief): self.root = root self.text = text self.bg = bg self.padx = padx self.pady = pady self.relief = relief def button_function(self): ButtonFunction() def make_button(self): button = tk.Button(self.root, text=self.text, bg=self.bg, padx=self.padx, pady=self.pady, relief=self.relief, command=self.button_function) button.grid() class Main: def __init__(self): self.root = tk.Tk() self.root.title("Application") self.root.geometry("400x300") self.root.columnconfigure(0, weight=1) self.root.rowconfigure(0, weight=1) def application(self): F = FrameClass(self.root, "BLACK", 5, 400*0.9, 300*0.9) frame = F.make_frame() button_color, padx, pady, relief = "GREY", 25, 10, tk.GROOVE B1 = ButtonClass(frame, "Button 1", button_color, padx, pady, relief) B1.make_button() self.root.mainloop() if __name__ == "__main__": M = Main() M.application()
这样修改后,Frame会始终保持你设置的初始尺寸,按钮会显示在Frame内部,不会再压缩Frame的大小。
内容的提问来源于stack exchange,提问作者python3 programmer
相关产品推荐
相关产品推荐

