Tkinter 如何将小部件放在并排使用pack的小部件下面?

Tkinter 如何将小部件放在并排使用pack的小部件下面?,tkinter,python,Tkinter,Python,我尝试将小部件放在如下位置: 我不明白为什么我的代码没有做到这一点,我试图在网上查找示例,但没有找到解决方案,我尝试的任何东西都没有使我更接近所要求的结果 这是到目前为止我的代码(如果您对代码中的任何内容有任何意见,请随时告诉我,因为这是我第一次尝试使用和GUI): 您可以在不使用附加帧的情况下,在仍然使用的情况下包含框对象,同时仍保持可调整大小 但在某些情况下,它更有条理:使用一个附加的框架来包含您的框对象,方法是使用父选项对其进行初始化 现在,框类中的小部件是全局根对象的子对象。这其实不是

我尝试将小部件放在如下位置:

我不明白为什么我的代码没有做到这一点,我试图在网上查找示例,但没有找到解决方案,我尝试的任何东西都没有使我更接近所要求的结果

这是到目前为止我的代码(如果您对代码中的任何内容有任何意见,请随时告诉我,因为这是我第一次尝试使用和GUI):

您可以在不使用附加帧的情况下,在仍然使用的情况下包含
对象,同时仍保持可调整大小

但在某些情况下,它更有条理:使用一个附加的框架来包含您的
对象,方法是使用父选项对其进行初始化

现在,
类中的小部件是全局
对象的子对象。这其实不是一个好的做法。因此,让我们首先传递并使用一个父对象来用于内部小部件

替换:

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


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

这使得您现在需要初始化对象,如下所示:

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
选项输入)


一般答复 一般来说,将一个小部件放在两个并排的小部件下面可以通过以下方式完成:

框架封装并排的小部件,然后简单地将
框架置于另一个小部件之上:

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()
使用:

在不使用其他帧的情况下,通过调用
pack
side='bottom'
作为第一个
pack
调用
下面的小部件
,如下所示:


通过创建全局
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
使用“空腔”模型。每个小部件都组织在一个未填充的空腔中。一旦该部件被放置,腔的该部分被填充,并且对于任何其他部件都不可用

在您的例子中,您希望底部的空腔被entry小部件填满,所以您应该首先打包它。然后,在剩余的上腔中,您可以并排放置两个框架,一个在左侧,一个在右侧

例如:

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
(或
place
grid
)语句都在同一个代码块中,这也非常非常有帮助。当你把它们分散在周围时,它就无法想象,也无法修复。此外,确保小部件具有适当的父级

你想干什么?可能提供图像?@Nae是否有特定的方法创建图像以向您展示,或者我应该使用基本的图像编辑软件?任何草图都应该足够。请参阅以了解修订历史记录。我可能过度编辑了这个问题。我尝试使用额外的框架来包含长方体对象(boxs),但它仍然不起作用。我实际上打算使用长方体作为长方体的框架,但我有一个小错误:D.行“self.root=root”来自上一次尝试,并且在box.root=boxs的上方,这与您的操作相同。非常感谢您的帮助。实际上,您可以在不使用任何其他框架(基于提供的图像)的情况下获得用户想要的布局。但是,用户提供的代码不仅仅包括三个小部件,这正是您的建议适合的时候。请注意,我编辑了标题以使其更具可读性,这可能是因为它导致了与实际问题的太多偏差。
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()
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()
...
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()
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()