簡體   English   中英

如何將小部件放在使用pack並排的小部件下方?

[英]How to put a widget beneath widgets that are side-by-side using pack?

我試着這樣放置小部件:

在此處輸入圖片說明

我不明白為什么我的代碼沒有做到這一點,試圖在網上查找示例,但沒有找到解決方案,我沒有嘗試使我更接近請求的結果。

到目前為止,這是我的代碼(如果您對代碼中的任何內容有任何評論,請隨時告訴我,因為這是我通常第一次嘗試使用和GUI):

from Tkinter import *


class box(object):

    def __init__ (self, colour,s):
        self.root = root
        self.listbox = Listbox(self.root, fg = colour, bg = 'black')
        self.s = s
        self.place_scrollbar()
        self.listbox.pack(side = self.s)


    def place_scrollbar(self):
        scrollbar = Scrollbar(self.root)
        scrollbar.pack(side = self.s, fill = Y)
        self.listbox.config(yscrollcommand = scrollbar.set)
        scrollbar.config(command = self.listbox.yview)

    def write(self, contenet):
        self.listbox.insert(END, contenet)

root = Tk()
root.resizable(False, False)
boxs = Frame(root)
boxs.pack()
box.root = boxs
server = box("red", LEFT)
client = box("green", RIGHT )
bf = Frame(root)
bf.pack(side = BOTTOM)
entry = Entry(bf,bg ='black', fg = 'white')
entry.pack()
root.mainloop()

可以 “T 做到這一點 ,而無需使用附加的幀來包含box對象,而仍然使用pack ,同時仍然保持可調整大小。

但是在某些情況下,它可以組織得更好:通過使用父選項進行初始化,使用附加框架來包含box對象。

現在, box類中的小部件是全局 root對象的子級。 這實際上不是一個好習慣。 因此,讓我們首先傳遞並使用一個父對象用於內部的小部件。

更換:

def __init__ (self, colour,s):
    self.root = root
    self.listbox = Listbox(self.root, ...)
    ...


def place_scrollbar(self):
    scrollbar = Scrollbar(self.root)
    ...

有:

def __init__ (self, parent, colour,s):
    self.parent= parent
    self.listbox = Listbox(self.parent, ...)
    ...


def place_scrollbar(self):
    scrollbar = Scrollbar(self.parent)
    ...

這樣一來,您現在就需要像下面這樣初始化該對象:

server = box(root, "red", LEFT)
client = box(root, "green", RIGHT )

現在我們可以傳遞父窗口小部件,讓我們創建一個包含它們的父框架。 實際上,已經有一個未使用的框架, boxs可以通過將其作為父類而不是root傳遞給它來使用它:

server = box(boxs, "red", LEFT)
client = box(boxs, "green", RIGHT )

現在一切看起來都很好,如果願意,可以選擇使條目占據盡可能多的剩余空間,目前,將fill='x'作為選項添加到條目pack和包含它的框架中:

bf.pack(side = BOTTOM, fill='x')
...
entry.pack(fill='x')

您的整個代碼應如下所示:

from Tkinter import *


class box(object):

    def __init__ (self, parent, colour,s):
        self.parent = parent
        self.listbox = Listbox(self.parent, fg = colour, bg = 'black')
        self.s = s
        self.place_scrollbar()
        self.listbox.pack(side = self.s)


    def place_scrollbar(self):
        scrollbar = Scrollbar(self.parent)
        scrollbar.pack(side = self.s, fill = Y)
        self.listbox.config(yscrollcommand = scrollbar.set)
        scrollbar.config(command = self.listbox.yview)

    def write(self, contenet):
        self.listbox.insert(END, contenet)

root = Tk()
root.resizable(False, False)
boxs = Frame(root)
boxs.pack()
box.root = boxs
server = box(boxs, "red", LEFT)
client = box(boxs, "green", RIGHT )
bf = Frame(root)
bf.pack(side = BOTTOM, fill='x')
entry = Entry(bf,bg ='black', fg = 'white')
entry.pack(fill='x')
root.mainloop()

或:使用grid代替pack (使用columnspan=2選項輸入)。


一般答案

通常,可以通過以下方式將一個小部件並排放置在兩個小部件之間:

frame封裝並排的小部件,然后簡單地將frame放在另一個小部件上方:

try:                        # In order to be able to import tkinter for
    import tkinter as tk    # either in python 2 or in python 3
except ImportError:
    import Tkinter as tk


def main():
    root = tk.Tk()
    side_by_side_widgets = dict()
    the_widget_beneath = tk.Entry(root)
    frame = tk.Frame(root)
    for name in {"side b", "y side"}:
        side_by_side_widgets[name] = tk.Label(frame, text=name)
        side_by_side_widgets[name].pack(side='left', expand=True)
    frame.pack(fill='x')
    the_widget_beneath.pack()
    root.mainloop()


if __name__ == '__main__':
    main()

使用grid

try:                        # In order to be able to import tkinter for
    import tkinter as tk    # either in python 2 or in python 3
except ImportError:
    import Tkinter as tk


def main():
    root = tk.Tk()
    side_by_side_widgets = dict()
    the_widget_beneath = tk.Entry(root)
    for index, value in enumerate({"side b", "y side"}):
        side_by_side_widgets[value] = tk.Label(root, text=value)
        side_by_side_widgets[value].grid(row=0, column=index)
    the_widget_beneath.grid(row=1, column=0, columnspan=2)
    root.mainloop()


if __name__ == '__main__':
    main()

如果不使用額外的框架,通過調用packthe_widget_beneathside='bottom'為第一pack的呼叫,在布萊恩的評論

try:                        # In order to be able to import tkinter for
    import tkinter as tk    # either in python 2 or in python 3
except ImportError:
    import Tkinter as tk


def main():
    root = tk.Tk()
    side_by_side_widgets = dict()
    the_widget_beneath = tk.Entry(root)
    the_widget_beneath.pack(side='bottom')
    for name in {"side b", "y side"}:
        side_by_side_widgets[name] = tk.Label(root, text=name)
        side_by_side_widgets[name].pack(side='left', expand=True)
    root.mainloop()


if __name__ == '__main__':
    main()

通過創建全局main方法,然后在其中添加腳本主體並調用,您可以更輕松地注意到全局對象的可靠性。

...
def main():
    root = Tk()
    root.resizable(False, False)
    boxs = Frame(root)
    boxs.pack()
    box.root = boxs
    server = box(boxs, "red", LEFT)
    client = box(boxs, "green", RIGHT )
    bf = Frame(root)
    bf.pack(side = BOTTOM, fill='x')
    entry = Entry(bf,bg ='black', fg = 'white')
    entry.pack(fill='x')
    root.mainloop()

if __name__ == '__main__':
    main()

如何將小部件放在使用pack並排的兩個小部件下面?

對於一個非常簡單的布局(如您的圖中所示),您只需要先將其包裝在底部。 這是因為pack使用“腔”模型。 每個小部件都組織在一個未填充的空腔中。 放置該小部件后,空腔的該部分將被填充,並且其他任何小部件均無法使用。

在您的情況下,您希望底部空腔填充條目小部件,因此您應該先打包它。 然后,在剩下的上腔中,可以並排放置兩個框架,一個在左側,另一個在右側。

例如:

import Tkinter as tk

root = tk.Tk()

entry = tk.Entry(root)
frame1 = tk.Frame(root, width=100, height=100, background="red")
frame2 = tk.Frame(root, width=100, height=100, background="green")

entry.pack(side="bottom", fill="x")
frame1.pack(side="left", fill="both", expand=True)
frame2.pack(side="right", fill="both", expand=True)

root.mainloop()

在您的問題中,事情變得更加復雜,因為您不僅僅擁有如標題所示的三個小部件,還擁有多個小部件,其中一些打包在根目錄中,而另一些打包在其他地方,而pack語句分散在各處。

使用pack時,最好將小部件分為垂直或水平切片,並且不要在同一組中將頂部/底部與左側/右側混合在一起。 似乎您正在嘗試用盒子來做,但是然后您就不這么做了–您的“盒子”實際上是兩個小部件。

底線:有條理。 如果給定父對象的所有pack (或placegrid )語句都在同一代碼塊中,這也確實會有所幫助。 當您將它們散布在周圍時,將無法可視化,也無法修復。 另外,請確保小部件具有適當的父級。

暫無
暫無

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

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