Tkinter GUI不在适当的位置

时间:2017-03-15 08:11:30

标签: python tkinter tk

我正在尝试创建一个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()

2 个答案:

答案 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,因此此框架的所有子项实际上都以子框架的子项结束。当您致电packgrid时,您最终会将其置于根窗口内。

因此,您应该将窗口小部件创建与窗口小部件布局分开。我建议你总是这样做,虽然从技术上来说,当你需要使用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几何经理看似奇怪而任性,但事实并非如此。你必须了解的一件事是你的行动顺序!

所以主要的算法就是:

  1. 创建一个(小部件或容器的)实例,并与其父级关联。
  2. 实例已打包。
  3. 换句话说:想象你正在建房子!在您的示例中,您开始在硬件商店或任何地方建造房屋,因此您的房屋不是根据您的计划建造的。

    试着想象每一帧都是房子的地板。其中的小部件是家具!所以首先你要用家具计划你的地板,然后按照你的意愿包装。

    我修改了你的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")
    

    <强>结果

    output

    <强>加成: 关于pack经理的保留和逻辑的问题: 我并不完全知道pack经理是如何在幕后工作的,但如果出现问题,你可以通过为你的框架添加边框来测试! 只需声明您的框架:FrameVar = Frame(parent, relief='raised', borderwidth=10)。如您所见 - 直接放置在root窗口中的外观小部件!

    所以我测试了3个变体(来自你的问题,来自我的答案和正确答案):

    1. 完全掏出一个(来自你的问题)
    2. totallyoutframed

      1. 部分外表(来自我的回答)
      2. partiallyoutframed

        1. 更正一个,所有项目都在框架中
        2. correctone

          更正代码

          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。仅当您喜欢全局名称空间污染时才使用通配符导入。