Tkinter创建多页面时grid函数失效及pack布局混用报错问题问询
报错原因
Tkinter有强制规则:同一个父容器下只能使用唯一一种布局管理器,不能混用pack、grid、place三种布局。
你当前的错误出在StartPage类中:你已经为父容器self(即StartPage本身的Frame容器)下的label组件用了grid布局,后续在同一个父容器下的日历、Enter按钮又用了pack布局,直接触发了冲突。
解决方案
有两种常用修复方案可选:
方案1:统一StartPage下的布局为grid
将原来用pack的日历、按钮全部改成grid布局即可,修改后的StartPage代码如下:
class StartPage(tk.Frame): #creating start page def __init__(self, parent, controller): tk.Frame.__init__(self,parent) label = tk.Label(self, text="StudyFriendO", font = LARGE_FONT) label.grid(row=1, column=2) cal = Calendar(self, background="#e0f6fc", disabledbackground="white", bordercolor="light blue", headersbackground="light blue", normalbackground="#e0f6fc", foreground="black", normalforeground='black', headersforeground='white', selectmode="day", year=2021, month=8, day=9) cal.grid(row=2, column=2, pady=20) # 原pack改为grid button1 = ttk.Button(self, text="Enter", command=lambda: controller.show_frame(HomePage)) button1.grid(row=3, column=2) # 原pack改为grid
如果需要调整组件对齐、跨列占宽等效果,可以额外配置grid的sticky、columnspan参数,以及用grid_rowconfigure、grid_columnconfigure设置行列权重。
方案2:嵌套Frame隔离不同布局
如果你确实希望部分组件用pack更方便,可以新增中间层Frame隔离布局,不同父容器使用不同布局不会冲突,示例代码如下:
class StartPage(tk.Frame): #creating start page def __init__(self, parent, controller): tk.Frame.__init__(self,parent) label = tk.Label(self, text="StudyFriendO", font = LARGE_FONT) label.grid(row=1, column=2) # 新增中间容器,用grid挂载到外层父容器 content_frame = tk.Frame(self) content_frame.grid(row=2, column=2) # 中间容器内部用pack放组件,不会和外层的grid冲突 cal = Calendar(content_frame, background="#e0f6fc", disabledbackground="white", bordercolor="light blue", headersbackground="light blue", normalbackground="#e0f6fc", foreground="black", normalforeground='black', headersforeground='white', selectmode="day", year=2021, month=8, day=9) cal.pack(pady=20 ) button1 = ttk.Button(content_frame, text="Enter", command=lambda: controller.show_frame(HomePage)) button1.pack()
注意事项
后续其他页面(HomePage、ToDoPage等)如果要切换为grid布局,也需要遵循同一个父容器仅用一种布局的规则,避免重复触发同类错误。
内容的提问来源于stack exchange,提问作者Minbutt
相关产品推荐
相关产品推荐

