[英]Tkinter pack() geometry manager confusion
就在我以為自己了解pack()
管理器時,遇到了以下問題:
我創建了兩個框架(每個框架都有一個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()
運行時,它會產生兩個垂直包裝的框架。 只需切換QuitBtn1
和QuitBtn
的名稱(將框架更改為簡單的按鈕),即可將包裝更改為水平。
我看了幾十個示例,這些示例似乎以某種方式避免了這種確切的結構。 我在這里做錯什么了嗎?
問題是您沒有給任何小部件提供父項,因此它們都默認為根窗口。 即使您認為按鈕在框架內部,也沒有。
因為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
在QuitBtn
框架內創建了一個按鈕小部件,並將其打包到該框架的頂部。 稍后,該框架(及其內容)將打包到主框架的左側。
將小部件的創建與小部件的布局分開也是很重要的。 當您執行諸如self.QUIT = QuitBtn(...).pack(...)
, self.QUIT
將被設置為None
因為這是pack(...)
返回的結果。 另外,根據我的經驗,將給定包含框架的所有布局移動到單獨的塊中,可以更輕松地管理布局。
一種方法是使用in_=
參數告訴pack
您要將每個小部件pack
內容。 所以:
from Tkinter import *
class QuitBtn(Frame):
def __init__(self):
Frame.__init__(self)
b = Button(text = "Quit", fg = "red", command = self.quit)
b.pack(in_=self) # Here
class HiBtn(Frame):
def __init__(self):
Frame.__init__(self)
b = Button(text = "Hi there", fg = "blue", command = self.quit)
b.pack(in_=self) # Here
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()
在框架內(每個按鈕在App框架內)產生按鈕的水平排列。
我認為我自己從未需要此功能,但是我也不記得曾經使用頂級類聲明小部件。
作為附帶說明,非常感謝您提供了演示相同問題的簡化代碼版本! 我希望這更常見。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.