我正在尝试创建一个Tkinter GUI,一个灰色框,顶部有一个标签,然后是一个下拉框,左边有一个描述它的标签,下面是另一个下拉框,左边有一个标签。相反,我将标签放在适当的位置,但随后两个下拉框和标签相互叠加,即使它们位于不同的框架中。
from Tkinter import *
import ttk
class review_gui():
def __init__(self):
self.root = Tk()
self.EDM_GUI(1)
self.root.mainloop()
def EDM_GUI(self, column):
self.EDM_frm = Frame(self.root, background = "grey")
self.EDM_frm.pack(side = "top")
EDM_Label_frm = Frame(self.EDM_frm).pack(side = "top")
EDM_DD_frm = Frame(self.EDM_frm).pack(side = "bottom")
EDM_DB_frm = Frame(EDM_DD_frm).pack(side = "top")
EDM_Port_frm = Frame(EDM_DD_frm).pack(side = "bottom")
EDM_lbl = Label(EDM_Label_frm, text="EDM", fg="black").pack()
EDM_DD_label = Label(EDM_DB_frm, text="Select EDM:", fg="black")
EDM_DD_label.pack(side="left")
EDM_Drop_Down = ttk.Combobox(EDM_DB_frm, state="readonly")
EDM_Drop_Down["values"] = ("One", "Two", "Three")
EDM_Drop_Down.pack(side="right")
EDM_P_label = Label(EDM_Port_frm, text="Select Portfolio:", fg="black")
EDM_P_label.pack(side="left")
Port_Drop_Down = ttk.Combobox(EDM_Port_frm, state="readonly")
Port_Drop_Down["values"] = ("One", "Two", "Three")
Port_Drop_Down.pack(side="right")
rg = review_gui()
答案 0 :(得分:2)
问题源于您在创建窗口小部件的同时调用pack
:
EDM_Label_frm = Frame(self.EDM_frm).pack(side = "top")
在python中,当你执行foo().bar()
时,结果就是bar()
返回的内容。因此,在Frame(...).pack(...)
的情况下,您将获得.pack(...)
返回的内容。 pack
始终返回None
,因此EDM_Label_frm
设置为None
。
由于EDM_Label_frm
设置为None
,因此此框架的所有子项实际上都以子框架的子项结束。当您致电pack
或grid
时,您最终会将其置于根窗口内。
因此,您应该将窗口小部件创建与窗口小部件布局分开。我建议你总是这样做,虽然从技术上来说,当你需要使用widget作为其他命令的参数时,你只需要这样做。
如果您进行了一次更改,UI将更接近您的预期。我发现最好总是将父级内的布局组合在一起,这样就可以更容易地获得布局的整体视图。在许多情况下,我认为当您将所有布局组合在一起时,它会产生更易读的代码。
例如:
EDM_Label_frm = Frame(self.EDM_frm)
EDM_DD_frm = Frame(self.EDM_frm)
EDM_DB_frm = Frame(EDM_DD_frm)
EDM_Port_frm = Frame(EDM_DD_frm)
self.EDM_frm.pack(side = "top")
EDM_Label_frm.pack(side = "top")
EDM_DD_frm.pack(side = "bottom")
EDM_DB_frm.pack(side = "top")
EDM_Port_frm.pack(side = "bottom")
答案 1 :(得分:1)
Standart pack
几何经理看似奇怪而任性,但事实并非如此。你必须了解的一件事是你的行动顺序!
所以主要的算法就是:
换句话说:想象你正在建房子!在您的示例中,您开始在硬件商店或任何地方建造房屋,因此您的房屋不是根据您的计划建造的。
试着想象每一帧都是房子的地板。其中的小部件是家具!所以首先你要用家具计划你的地板,然后按照你的意愿包装。
我修改了你的EDM_GUI
功能,它看起来像你想要的那样工作!请记住避免在一行中声明和打包,因为pack
会返回None
。
示例强>:
def EDM_GUI(self, column):
self.EDM_frm = Frame(self.root, background="grey")
self.EDM_frm.pack()
EDM_Label_frm = Frame(self.EDM_frm).pack()
EDM_DD_frm = Frame(self.EDM_frm).pack()
EDM_DB_frm = Frame(EDM_DD_frm)
EDM_Port_frm = Frame(EDM_DD_frm)
EDM_lbl = Label(EDM_Label_frm, text="EDM", fg="black").pack()
EDM_DD_label = Label(EDM_DB_frm, text="Select EDM:", fg="black")
EDM_DD_label.pack(side="left")
EDM_Drop_Down = ttk.Combobox(EDM_DB_frm, state="readonly")
EDM_Drop_Down["values"] = ("One", "Two", "Three")
EDM_Drop_Down.pack(side="right")
EDM_DB_frm.pack(side="top")
EDM_P_label = Label(EDM_Port_frm, text="Select Portfolio:", fg="black")
EDM_P_label.pack(side="left")
Port_Drop_Down = ttk.Combobox(EDM_Port_frm, state="readonly")
Port_Drop_Down["values"] = ("One", "Two", "Three")
Port_Drop_Down.pack(side="right")
EDM_Port_frm.pack(side="bottom")
<强>结果强>:
<强>加成强>:
关于pack
经理的保留和逻辑的问题:
我并不完全知道pack
经理是如何在幕后工作的,但如果出现问题,你可以通过为你的框架添加边框来测试!
只需声明您的框架:FrameVar = Frame(parent, relief='raised', borderwidth=10)
。如您所见 - 直接放置在root
窗口中的外观小部件!
所以我测试了3个变体(来自你的问题,来自我的答案和正确答案):
更正代码:
def EDM_GUI(self, column):
self.EDM_frm = Frame(self.root)
EDM_Label_frm = Frame(self.EDM_frm)
EDM_lbl = Label(EDM_Label_frm, text="EDM", fg="black").pack()
EDM_Label_frm.pack()
EDM_DD_frm = Frame(self.EDM_frm)
EDM_DB_frm = Frame(EDM_DD_frm)
EDM_DD_label = Label(EDM_DB_frm, text="Select EDM:", fg="black")
EDM_DD_label.pack(side="left")
EDM_Drop_Down = ttk.Combobox(EDM_DB_frm, state="readonly")
EDM_Drop_Down["values"] = ("One", "Two", "Three")
EDM_Drop_Down.pack(side="right")
EDM_DB_frm.pack(side="top")
EDM_Port_frm = Frame(EDM_DD_frm)
EDM_P_label = Label(EDM_Port_frm, text="Select Portfolio:", fg="black")
EDM_P_label.pack(side="left")
Port_Drop_Down = ttk.Combobox(EDM_Port_frm, state="readonly")
Port_Drop_Down["values"] = ("One", "Two", "Three")
Port_Drop_Down.pack(side="right")
EDM_Port_frm.pack(side="bottom")
EDM_DD_frm.pack()
self.EDM_frm.pack()
P.S。仅当您喜欢全局名称空间污染时才使用通配符导入。