2015-04-06 75 views
1

就在我以爲我明白了pack()經理,我來到了以下問題:Tkinter的包()幾何管理混亂

我創建了兩個幀(每一個Button),並希望他們水平收拾另一個框架(這是'主要'框架)。出於某種原因,它們呈現垂直。如果我用一個簡單的按鈕替換第一幀,則使用相同的pack()指令,按鈕+第二幀水平打包爲

下面是程序的蒸餾水(但工作)版本:

from Tkinter import * 

class QuitBtn1(Button): 
    def __init__(self): 
     Button.__init__(self) 
     self["text"] = "Quit" 
     self["fg"] = "red" 
     self["command"] = self.quit 

class QuitBtn(Frame): 
    def __init__(self): 
     Frame.__init__(self) 

     b = Button(text = "Quit", fg = "red", command = self.quit) 
     b.pack() 

class HiBtn(Frame): 
    def __init__(self): 
     Frame.__init__(self) 

     b = Button(text = "Hi there", fg = "blue", command = self.quit) 
     b.pack() 

class App(Frame): 
    def __init__(self, master = None): 
     Frame.__init__(self, master) 
     self.pack() 
     self.createWidgets() 

    def say_hi(self): 
     print "hi there, everyone!" 

    def createWidgets(self): 
     self.QUIT = QuitBtn().pack(side = LEFT) 
     self.hi_there = HiBtn().pack(side = LEFT) 


root = Tk() 
app = App(master = root) 
app.mainloop() 
root.destroy() 

運行方式,它產生兩個垂直包裝,幀。只需切換QuitBtn1QuitBtn(將框架更改爲簡單按鈕)的名稱即可將包裝更改爲水平。

我看了數以萬計的例子,這似乎以某種方式避免了這個確切的結構。我在這裏做錯了什麼?

回答

1

一種方法是使用參數in_=告訴pack要打包每個窗口小部件的內容。所以:

可生產按鈕的幀中的水平佈置(每個應用程序框架內)。

enter image description here

我不認爲我曾經需要這一點我自己,但我不記得使用頂級類或者曾經宣佈部件。

作爲一個方面說明,非常感謝您提供了代碼的蒸餾版本,以展示相同的問題!我希望這更常見。

+0

感謝您的出色答覆!在大型項目中,這並不是那麼容易,它具有更多的框架和更復雜的結構,但是提供了您提供的指示,我懷疑我可以到達那裏......有很多'介紹...'網上的教程,但很少有更高級的教程。 – jcoppens

3

問題是,你沒有給你的任何一個小部件的父母,所以他們都默認爲根窗口。即使你認爲按鈕在框架內,但它們不是。

因爲pack的默認設置是沿着頂部放置東西,所以當您在按鈕上調用pack()時,它們被堆疊在根窗口中。你的兩個框架,因爲沒有任何內容,有1x1的大小,所以你看不到它們。 被打包在左邊,你只是看不到它們。

解決方案是正確地嵌套您的小部件。例如:

class QuitBtn(Frame): 
    def __init__(self, parent): 
     Frame.__init__(self, parent) 

     b = Button(self, text = "Quit", fg = "red", command = self.quit) 
     b.pack() 

def createWidgets(self): 
    self.QUIT = QuitBtn(self) 
    ... 
    self.QUIT.pack(side = LEFT) 
    ... 

上面在QuitBtn框架內創建了一個按鈕小部件,並將其打包到該框架的頂部。之後,該框架(及其內容)將被打包到主框架的左側。

將小部件的創建與小部件的佈局分開也很重要。當您執行類似self.QUIT = QuitBtn(...).pack(...)之類的操作時,self.QUIT將被設置爲None,因爲那是pack(...)返回的值。此外,根據我的經驗,將給定包含框架的所有佈局移動到單獨的塊中,可以更輕鬆地管理佈局。