簡體   English   中英

如何在已打包到左側的現有小部件下方打包 tkinter 小部件?

[英]How to pack a tkinter widget underneath an existing widget that has been packed to the left side?

我正在嘗試編寫一個基本的 Tkinter GUI,它的頂部有一個Text小部件,然后一個Button小部件在其下方左對齊,然后是Button下方的另一個Text小部件。 我遇到的問題是,在將Button小部件打包到左側之后,當我再打包第二個Text小部件時,它會將其放在右側的按鈕旁邊,而不是按鈕下方。 無論我為第二個Text小部件設置了side參數,這都會發生這里有一段簡單的代碼演示了這種行為:

from Tkinter import *

root = Tk()

w = Text(root)
w.pack()

x = Button(root, text="Hi there!")
x.pack(side=LEFT)

y = Text(root)
y.pack(side=BOTTOM)

root.mainloop()

那么我將如何設置第二個Text小部件,使其出現在按鈕下方,而不是它的右側?

布局問題一般有兩種解決方案:

  1. 切換到使用網格。 像您想要完成的那樣進行布局變得非常容易。 Grid 可以解決大約 95% 的所有布局問題(當您想到它時,這真是太神奇了——Tk 只需一個經理就可以完成大多數工具包需要六個才能完成的工作!)

  2. 使用多個框架。 如果某些小部件需要從上到下堆疊,而一些小部件需要從左到右堆疊,那么您無法總是獲得想要的東西,將所有東西都打包到一個框架中。 布局的從上到下部分使用一個框架,從左到右的內容使用附加框架。

還要意識到小部件不必是它們被打包/網格化的小部件的子部件。 您可以使用“in”參數將小部件放入其父容器之外的其他容器中。

例如,在您的特定示例中,您可以創建三個框架,頂部、中間、底部。 將這些從上到下打包到頂層窗口中。 然后您可以將第一個文本小部件打包在頂部,按鈕或按鈕水平放置在中間,另一個文本小部件位於底部。

這種方法的優點是它可以更輕松地在將來更改布局(根據我的經驗,這種情況總是在某些時候發生)。 您不必重新設置任何小部件的父級,只需將它們打包/放置/網格放在其他容器中即可。

在您的簡短示例中,它沒有太大區別,但對於復雜的應用程序,此策略可以挽救生命。

我最好的建議是:布局不是事后的想法。 做一點計划,甚至可能花五分鍾在一些方格紙上畫畫。 首先確定應用程序的主要區域,並為每個區域使用框架或其他容器(窗格窗口、筆記本等)。 一旦你有了這些,對每個部分執行相同的分而治之的方法。 這使您可以為應用程序的不同部分使用不同類型的布局。 工具欄采用水平布局,表單可能采用垂直布局等。

我最初誤解了包裝是如何工作的,並且沒有意識到當我執行x.pack(side=LEFT)時整個左側都被“聲明”。 我在閱讀這篇文章和 Alex 在這里的回答后發現的是,我並不是真的在將x打包到左側之后,而是將它錨定到左側,使用anchor=W (W 代表西方)而不是side=LEFT 我修改后的代碼片段看起來像這樣:

from tkinter import *

root = Tk()

w = Text(root)
w.pack()

x = Button(root, text="Hi there!")
x.pack(anchor=W)

y = Text(root)
y.pack(side=BOTTOM)

root.mainloop()

這樣x不再“聲稱”左側,它只是在其空間塊內與左側(或西部)對齊。

打包是按照 .pack 方法被調用的順序進行的,所以一旦 x 已經“聲明”了左側,就是這樣——它將占據其父級的左側部分,而其父級中的所有其他內容都將在其右側。 您需要一個框架來“調解”,例如...:

from Tkinter import *

root = Tk()

w = Button(root, text="Mysterious W")
w.pack()

f = Frame(root)
x = Button(f, text="Hi there!")
x.pack()

y = Button(f, text="I be Y")
y.pack(side=BOTTOM)

f.pack(side=LEFT)

root.mainloop()

(將 Texts 更改為 Buttons 僅用於更直接的布局可見性-此 Mac 上的 Tkinter 在獲得焦點之前不會清楚地顯示 Texts,但 Buttons 非常清晰;-)。

使用 Mosaic Canvas Widget Sets 內部組件(與 Tk 非常相似)的方式與 WebView 相同。 訣竅在於,第二個相同命名的框架對象作為塊級浮點(inline:block;)用於放置在它之后的所有內容,並且已經調用“fr”的所有內容將自動在其內部重新開始。

您可以讓許多 TOP 對齊的小部件執行此操作,只需添加另一個相同的命名框架,您希望在 side=LEFT 之間斷開。 在底部之后也有效。

fr=Frame(root)
fr.pack(fill=X, side=TOP)

block1=Label(fr)
block1.pack(side=LEFT)

block2=Label(fr)
block2.pack(side=LEFT)

block3=Button(fr)
block3.pack(side=LEFT)

# NAME IT THE SAME ID NAME AS THE FIRST MAIN FRAME...
fr=Frame(root)
fr.pack(fill=X, side=TOP)

# These NOW jump into the second Frame breaking the side=LEFT in new Frame
block4=Label(fr) 
block4.pack(side=LEFT)

block5=Label(fr)
block5.pack(side=LEFT)

# AND THEY CONTINUE GOING side=LEFT AFTERWARDS.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM