2017-03-15 82 views
0

我想創建一個Tkinter圖形用戶界面的頂部有一個標籤的灰色框,然後在下面的一個下拉框和左邊的標籤描述它,然後在下面的另一個下拉框左邊有一個標籤。相反,我在適當的位置獲得標籤,但是然後兩個下拉框和標籤彼此重疊,即使它們處於不同的框架中。Tkinter圖形用戶界面不在適當的地方

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() 

回答

1

standart pack幾何管理器可能看起來奇怪和任性,但事實並非如此。你必須明白的一件事是你的行動順序!

所以主alghorithm是這樣的:

  1. 一個實例(窗口小部件或容器的)被創建,並與它的父相關聯。
  2. 實例打包。

換句話說:想象你正在蓋房子!在你的例子中,你開始在五金商店或任何地方建造房子,所以你的房子不是按照你的計劃建造的。

試着想象每個框架是房子的地板。而它裏面的小工具就是傢俱!所以,首先你要用傢俱來規劃你的地板,然後按照你的意願包裝它。

我修改了一下你的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)。正如你所看到的 - outframed小部件直接放在你的root窗口!

所以我試驗了3個變種(從你的問題,從我的答案和正確的):

  1. 共outframed一個(從你的問題)

totallyoutframed

  • 部分鏤空一個(來自我的回答)
  • partiallyoutframed

  • 正確的,以幀
  • 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.僅當您喜歡全局名稱空間污染時才使用通配符導入。

    +0

    感謝常識,所以我正在收拾框架,我把他們的小部件之前,當你把小工具在他們,他們都擠滿了。一個問題,當我創建EDM_Label_frm和EDM_DD_frm時,它保留了打包順序,並將EDM_Label_frm放在EDM_DD_frm之前。但是當我創建兩個框架EDM_DB_frm和EDM_Port_frm時,它將它們合併在一起並且不保留打包順序? –

    +0

    @Christopher Ell,我更新了我的答案,以表明你對保存的看法有多不對。 – CommonSense

    +1

    重新_「我不完全知道包管理器是如何工作的 - _ - 規範描述在這裏:http://tcl.tk/man/tcl8。5/TkCmd/pack.htm#M26 –

    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作爲其他命令的參數時才需要這樣做。

    如果您做出這樣的改變,界面將看起來更接近您的期望。我發現最好始終將父級佈局組合在一起,以便更容易地獲得佈局的總體視圖。在很多情況下,我認爲當你將全部佈局在一起時,它會提高可讀性。

    例如:

    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") 
    
    +0

    感謝您的幫助 –