Tkinter Pack方法的困惑

时间:2019-08-07 08:40:15

标签: python tkinter

我不明白为什么打包管理器不会让您在顶部打包的小部件下方打包。我的以下代码的预期输出将是

 A
 B
C D 
 E

但是它只会显示:

 A
 B
C D
import tkinter as tk

root = tk.Tk()
w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.state('zoomed')
root.geometry("%dx%d+0+0" % (w-15, h-75))
A = tk.LabelFrame(root,text='A', bd=2)
B = tk.LabelFrame(root,text='B', bd=2)
C = tk.LabelFrame(root,text='C', bd=2)
D = tk.LabelFrame(root,text='D', bd=2)
E = tk.LabelFrame(root,text='E', bd=2)

A.pack(fill=tk.BOTH, expand=tk.TRUE)
B.pack(fill=tk.BOTH, expand=tk.TRUE)
C.pack(side=tk.LEFT,fill=tk.BOTH, expand=tk.TRUE)
D.pack(side=tk.RIGHT,fill=tk.BOTH, expand=tk.TRUE)
E.pack(side=tk.BOTTOM, fill=tk.BOTH, expand=tk.TRUE)

root.mainloop()

4 个答案:

答案 0 :(得分:4)

简而言之,打包程序并非旨在直接创建您要创建的布局。您可以执行此操作,但是它需要一些额外的帧。在这种明显要创建网格的特殊情况下,grid无疑是更好的选择。

在解释为什么会这样之前,让我提出一个解决方案。创建另一个称为“ CD”的框架,该框架将用于同时容纳CD。然后,您可以将C放在左侧,将D放在右侧,然后将此框放在B下方。这就是您使用打包机获得所需结果的方式。

A = tk.LabelFrame(root,text='A', bd=2)
B = tk.LabelFrame(root,text='B', bd=2)
CD = tk.Frame(root)
C = tk.LabelFrame(CD,text='C', bd=2)
D = tk.LabelFrame(CD,text='D', bd=2)
E = tk.LabelFrame(root,text='E', bd=2)

C.pack(side=tk.LEFT,fill=tk.BOTH, expand=tk.TRUE)
D.pack(side=tk.RIGHT,fill=tk.BOTH, expand=tk.TRUE)

A.pack(fill=tk.BOTH, expand=tk.TRUE)
B.pack(fill=tk.BOTH, expand=tk.TRUE)
CD.pack(fill=tk.BOTH, expand=tk.TRUE)
E.pack(side=tk.BOTTOM, fill=tk.BOTH, expand=tk.TRUE)

解释包装机

打包机通过沿未分配空间的一侧保留一块空间来工作。 在将小部件打包到顶部或底部时,此分配的空间占用未分配空间的全部宽度,而在左侧或右侧打包时,该占用的空间占用整个高度。。这是重要的细节。 / p>

让我尝试用一​​些屏幕截图来描述它。在所有情况下,以下屏幕截图都不会显示框架,而是显示打包程序正在管理的已分配和未分配空间的数量。

当您将A放在顶部时(如果未指定侧面,则默认为顶部),则会为根窗口的整个宽度保留一块空间。并且由于您将其打包到顶部,因此剩余的唯一空间在A以下。从这一点开始,A的左侧或右侧都无法打包。

(实际上,您可以使用一些高级选项将其放在左侧或右侧,但这超出了本说明的范围)

available space after A

当您将B放在顶部时,唯一可用空间在A下。同样,由于您将其打包在顶部,因此在打包B之后,现在唯一可用的可用空间将在B之下。

available space after B

当您将C放在左侧时,将为剩余空间的全部高度保留一个空间。这意味着将无法在C下放置任何内容。所有剩余空间都在C的右侧,在B的下方。

available space after C

  1. 打包D时,它必须位于C的右侧和B的下方。由于您将其打包在右侧,因此它将保留D上方和下方的所有剩余垂直空间。

available space after D

E放在底部时,它只能走到B下方,C右侧和D左侧。

available space after E

由于打包程序沿一面分配所有空间的性质,当所有小部件都放置在同一轴上(垂直或水平堆叠)时,打包程序最有效。当您要像使用CD那样切换轴时,通常最好将它们放在单独的框架中。在该框架内,您可以从左到右放置小部件,但是该框架可以像其他小部件一样在上下轴线上保持不变。

注意:这就是代码中实际发生的情况:E被压缩在CD之间。由于各种原因,它不可见,但是如果您给它一个明确的尺寸和颜色,它将显示出来。

更多信息

可以在tcl/tk man pages for pack中找到关于封隔器算法的权威描述。

答案 1 :(得分:1)

一种解决方法是将C + D帧打包在一个临时LabelFrame中,然后将其打包在B之下。

import tkinter as tk

root = tk.Tk()
w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.state('zoomed')
root.geometry("%dx%d+0+0" % (w-15, h-75))
A = tk.LabelFrame(root,text='A', bd=2)
B = tk.LabelFrame(root,text='B', bd=2)

temp = tk.LabelFrame(root)

C = tk.LabelFrame(temp,text='C', bd=2)
D = tk.LabelFrame(temp,text='D', bd=2)
E = tk.LabelFrame(root,text='E', bd=2)

A.pack(fill=tk.BOTH, expand=tk.TRUE)
B.pack(fill=tk.BOTH, expand=tk.TRUE)
C.pack(side=tk.LEFT,fill=tk.BOTH, expand=tk.TRUE)
D.pack(side=tk.RIGHT,fill=tk.BOTH, expand=tk.TRUE)
temp.pack(expand=tk.TRUE, fill=tk.BOTH)
E.pack(side=tk.BOTTOM, fill=tk.BOTH, expand=tk.TRUE)

root.mainloop()

答案 2 :(得分:0)

tkinter包是所有三个几何管理器之一。它有助于指定所有tkinter小部件的几何形状。这是代码示例。

from tkinter import * 

window = Tk()

Label(window,text = "Text").pack()

window.mainloop()

有关更多信息,请参阅tkinter pack

上的本教程

答案 3 :(得分:-1)

我建议您切换到放置方法。它更加简单和精确。 例如,如果您的w = 15且h = 75 C.place(x = 2,y = 2)放在顶部和左侧。