如何让Python Tkinter脚本中的LabelFrame保持水平对齐?
问题描述
我正在制作第一个Python GUI,使用Tkinter库。我添加了多个LabelFrame,每个LabelFrame内包含数量不同的Radiobutton,其中一个LabelFrame有3个Radiobutton,导致它与其他LabelFrame不在同一水平线上。我尝试过使用height属性和调整内边距,但没有效果。以下是我的代码:
#!/usr/bin/python3 import tkinter as tk from tkinter import * from tkinter import ttk top = tk.Tk() top.resizable(True, True) # General Category GenInfoLabel = tk.LabelFrame(top,text="General Information", fg="blue") GenInfoLabel.grid(column=0,row=0, padx=10, pady=5) # One One_Frame = tk.LabelFrame(GenInfoLabel,text="One", fg="blue") One_Frame.grid(column=1, row=1) def One_Call(): One_Sel=One_Var.get() if One_Sel == 1: One_ = 1 elif One_Sel == 2: One_ = 2 One_Var = tk.IntVar() rad_One_V1 = tk.Radiobutton(One_Frame, text="1", variable = One_Var, value=1, command=One_Call) rad_One_V1.grid(column=0, row=0, sticky=tk.W, columnspan=3) rad_One_V2 = tk.Radiobutton(One_Frame, text="2", variable = One_Var, value=2, command=One_Call) rad_One_V2.grid(column=0, row=1, sticky=tk.W, columnspan=3) # Two Two_Frame = tk.LabelFrame(GenInfoLabel , text="Two", fg="blue") Two_Frame.grid(column=2, row=1) def Two_Call(): Two_Sel=Two_Var.get() if Two_Sel == 1: Two_ = 1 elif Two_Sel == 2: Two_ = 2 Two_Var = tk.IntVar() rad_Two_1 = tk.Radiobutton(Two_Frame, text="1", variable = Two_Var, value=1, command=Two_Call) rad_Two_1.grid(column=0, row=0, sticky=tk.W, columnspan=3) rad_Two_2 = tk.Radiobutton(Two_Frame, text="2", variable = Two_Var, value=2, command=Two_Call) rad_Two_2.grid(column=0, row=1, sticky=tk.W, columnspan=3) # Three ThreeFrame = tk.LabelFrame(GenInfoLabel, text="Three", fg="blue") ThreeFrame.grid(column=3, row=1) def ThreeCall(): ThreeSel=ThreeVar.get() if ThreeSel == 1: Three = 1 elif ThreeSel == 2: Three = 2 ThreeVar = tk.IntVar() radThree1 = tk.Radiobutton(ThreeFrame, text="Yes", variable = ThreeVar, value=1, command=ThreeCall) radThree1.grid(column=0, row=0, sticky=tk.W, columnspan=3) radThree2 = tk.Radiobutton(ThreeFrame, text="No", variable = ThreeVar, value=2, command=ThreeCall) radThree2.grid(column=0, row=1, sticky=tk.W, columnspan=3) # Four FourFrame = tk.LabelFrame(GenInfoLabel, text="Four", fg="blue") FourFrame.grid(column=4, row=1) def FourCall(): FourSel=FourVar.get() if FourSel == 1: Four = 1 elif FourSel == 2: Four = 2 FourVar = tk.IntVar() radFour1 = tk.Radiobutton(FourFrame, text="1", variable = FourVar, value=1, command=FourCall) radFour1.grid(column=0, row=0, sticky=tk.W, columnspan=3) radFour2 = tk.Radiobutton(FourFrame, text="2", variable = FourVar, value=2, command=FourCall) radFour2.grid(column=0, row=1, sticky=tk.W, columnspan=3) # Five FiveFrame = tk.LabelFrame(GenInfoLabel, text="Five", fg="blue") FiveFrame.grid(column=5, row=1) def FiveCall(): FiveSel=FiveVar.get() if FiveSel == 1: Five = 1 elif FiveSel == 2: Five = 2 elif FiveSel == 3: Five = 3 FiveVar = tk.IntVar() radFive1 = tk.Radiobutton(FiveFrame, text="1", variable = FiveVar, value=1, command=FiveCall) radFive1.grid(column=0, row=0, sticky=tk.W, columnspan=3) radFive2 = tk.Radiobutton(FiveFrame, text="2", variable = FiveVar, value=2, command=FiveCall) radFive2.grid(column=0, row=1, sticky=tk.W, columnspan=3) radFive3 = tk.Radiobutton(FiveFrame, text="3", variable = FiveVar, value=3, command=FiveCall) radFive3.grid(column=0, row=2, sticky=tk.W, columnspan=3) # Six SixFrame = tk.LabelFrame(GenInfoLabel, text="Six", fg="blue") SixFrame.grid(column=6, row=1) def SixCall(): SixSel=SixVar.get() if SixSel == 1: Six = 1 elif SixSel == 2: Six = 2 SixVar = tk.IntVar() radSix1 = tk.Radiobutton(SixFrame, text="1", variable = SixVar, value=1, command=SixCall) radSix1.grid(column=0, row=0, sticky=tk.W, columnspan=3) radSix2 = tk.Radiobutton(SixFrame, text="2", variable = SixVar, value=2, command=SixCall) radSix2.grid(column=0, row=1, sticky=tk.W, columnspan=3) for child in GenInfoLabel.winfo_children(): child.grid_configure(padx=8) # Display Form top.mainloop()
请问如何修改代码使所有LabelFrame保持水平对齐?
解决方法
要让所有LabelFrame保持水平对齐,核心是统一它们的垂直对齐规则,以下是两种简单有效的实现方式:
方法1:设置grid的sticky参数为顶部对齐
在每个LabelFrame的grid调用中添加sticky="n",强制所有LabelFrame靠顶部对齐,这样即使内部控件数量不同,顶部边缘也会保持在同一水平线:
# 示例:修改单个LabelFrame的grid代码 One_Frame.grid(column=1, row=1, sticky="n") # 其余所有LabelFrame的grid都添加该参数 Two_Frame.grid(column=2, row=1, sticky="n") ThreeFrame.grid(column=3, row=1, sticky="n") FourFrame.grid(column=4, row=1, sticky="n") FiveFrame.grid(column=5, row=1, sticky="n") SixFrame.grid(column=6, row=1, sticky="n")
方法2:统一所有LabelFrame的高度(可选)
如果希望所有LabelFrame高度完全一致,可以先获取最高LabelFrame的高度,再将其他LabelFrame设置为相同高度,同时配合sticky参数让内部控件对齐:
# 先让GUI渲染一次以获取准确高度 top.update_idletasks() # 获取包含3个单选按钮的LabelFrame高度 target_height = FiveFrame.winfo_height() # 给其他LabelFrame设置统一高度 One_Frame.config(height=target_height) Two_Frame.config(height=target_height) ThreeFrame.config(height=target_height) FourFrame.config(height=target_height) SixFrame.config(height=target_height) # 同时设置sticky让内部控件顶部对齐 One_Frame.grid(column=1, row=1, sticky="n") # 其余Frame同理
修改后的完整代码
以下是添加了sticky="n"参数后的完整运行代码:
#!/usr/bin/python3 import tkinter as tk from tkinter import * from tkinter import ttk top = tk.Tk() top.resizable(True, True) # General Category GenInfoLabel = tk.LabelFrame(top,text="General Information", fg="blue") GenInfoLabel.grid(column=0,row=0, padx=10, pady=5) # One One_Frame = tk.LabelFrame(GenInfoLabel,text="One", fg="blue") One_Frame.grid(column=1, row=1, sticky="n") def One_Call(): One_Sel=One_Var.get() if One_Sel == 1: One_ = 1 elif One_Sel == 2: One_ = 2 One_Var = tk.IntVar() rad_One_V1 = tk.Radiobutton(One_Frame, text="1", variable = One_Var, value=1, command=One_Call) rad_One_V1.grid(column=0, row=0, sticky=tk.W, columnspan=3) rad_One_V2 = tk.Radiobutton(One_Frame, text="2", variable = One_Var, value=2, command=One_Call) rad_One_V2.grid(column=0, row=1, sticky=tk.W, columnspan=3) # Two Two_Frame = tk.LabelFrame(GenInfoLabel , text="Two", fg="blue") Two_Frame.grid(column=2, row=1, sticky="n") def Two_Call(): Two_Sel=Two_Var.get() if Two_Sel == 1: Two_ = 1 elif Two_Sel == 2: Two_ = 2 Two_Var = tk.IntVar() rad_Two_1 = tk.Radiobutton(Two_Frame, text="1", variable = Two_Var, value=1, command=Two_Call) rad_Two_1.grid(column=0, row=0, sticky=tk.W, columnspan=3) rad_Two_2 = tk.Radiobutton(Two_Frame, text="2", variable = Two_Var, value=2, command=Two_Call) rad_Two_2.grid(column=0, row=1, sticky=tk.W, columnspan=3) # Three ThreeFrame = tk.LabelFrame(GenInfoLabel, text="Three", fg="blue") ThreeFrame.grid(column=3, row=1, sticky="n") def ThreeCall(): ThreeSel=ThreeVar.get() if ThreeSel == 1: Three = 1 elif ThreeSel == 2: Three = 2 ThreeVar = tk.IntVar() radThree1 = tk.Radiobutton(ThreeFrame, text="Yes", variable = ThreeVar, value=1, command=ThreeCall) radThree1.grid(column=0, row=0, sticky=tk.W, columnspan=3) radThree2 = tk.Radiobutton(ThreeFrame, text="No", variable = ThreeVar, value=2, command=ThreeCall) radThree2.grid(column=0, row=1, sticky=tk.W, columnspan=3) # Four FourFrame = tk.LabelFrame(GenInfoLabel, text="Four", fg="blue") FourFrame.grid(column=4, row=1, sticky="n") def FourCall(): FourSel=FourVar.get() if FourSel == 1: Four = 1 elif FourSel == 2: Four = 2 FourVar = tk.IntVar() radFour1 = tk.Radiobutton(FourFrame, text="1", variable = FourVar, value=1, command=FourCall) radFour1.grid(column=0, row=0, sticky=tk.W, columnspan=3) radFour2 = tk.Radiobutton(FourFrame, text="2", variable = FourVar, value=2, command=FourCall) radFour2.grid(column=0, row=1, sticky=tk.W, columnspan=3) # Five FiveFrame = tk.LabelFrame(GenInfoLabel, text="Five", fg="blue") FiveFrame.grid(column=5, row=1, sticky="n") def FiveCall(): FiveSel=FiveVar.get() if FiveSel == 1: Five = 1 elif FiveSel == 2: Five = 2 elif FiveSel == 3: Five = 3 FiveVar = tk.IntVar() radFive1 = tk.Radiobutton(FiveFrame, text="1", variable = FiveVar, value=1, command=FiveCall) radFive1.grid(column=0, row=0, sticky=tk.W, columnspan=3) radFive2 = tk.Radiobutton(FiveFrame, text="2", variable = FiveVar, value=2, command=FiveCall) radFive2.grid(column=0, row=1, sticky=tk.W, columnspan=3) radFive3 = tk.Radiobutton(FiveFrame, text="3", variable = FiveVar, value=3, command=FiveCall) radFive3.grid(column=0, row=2, sticky=tk.W, columnspan=3) # Six SixFrame = tk.LabelFrame(GenInfoLabel, text="Six", fg="blue") SixFrame.grid(column=6, row=1, sticky="n") def SixCall(): SixSel=SixVar.get() if SixSel == 1: Six = 1 elif SixSel == 2: Six = 2 SixVar = tk.IntVar() radSix1 = tk.Radiobutton(SixFrame, text="1", variable = SixVar, value=1, command=SixCall) radSix1.grid(column=0, row=0, sticky=tk.W, columnspan=3) radSix2 = tk.Radiobutton(SixFrame, text="2", variable = SixVar, value=2, command=SixCall) radSix2.grid(column=0, row=1, sticky=tk.W, columnspan=3) for child in GenInfoLabel.winfo_children(): child.grid_configure(padx=8) # Display Form top.mainloop()
内容的提问来源于stack exchange,提问作者Cooler Mann
相关产品推荐
相关产品推荐

