grid()
和pack()
对大多数需求来说已经足够精准了。你只需要学习如何正确使用这些布局管理器。实际上,几乎从来不需要使用place()
。它有其用途,但并不是一般 GUI 设置的最佳选择。也很难管理更新你的代码。
更新:回答您在评论中的问题:
行配置是指将每一行都设置为 1 像素,因为权重吗?我知道我可以在整个程序上绘制一个网格,但我不知道我的程序有多少行、列。因此我找不到中心点。
权重用于告诉特定行或列应该以与其周围其他行和列在同一网格/容器内的比率进行调整大小。默认权重为零。当我们将权重设置为 1 时,该行或列将以相同的速率随窗口一起调整大小。
看看这个示例代码:
import tkinter as tk
root=tk.Tk()
center_frame = tk.Frame(root)
center_frame.grid(row=1, column=1, sticky='nsew')
tk.Label(center_frame, text='Name/ID').grid(row=0, column=0)
tk.Label(center_frame, text='Password').grid(row=1, column=0)
tk.Button(center_frame, text='Enter').grid(row=2, column=1)
root.mainloop()
结果:
![enter image description here](https://istack.dev59.com/6wV4B.webp)
在上面的示例中,您会发现当您调整窗口大小时,小部件不会移动。这是因为我们没有指示tkinter允许任何行或列移动。
如果我们将此权重添加到程序中
root.rowconfigure(0, weight=1)
:
那么我们就会得到这个效果:
![enter image description here](https://istack.dev59.com/GXAxe.webp)
接下来添加这个root.rowconfigure(2, weight=1)
:
![enter image description here](https://istack.dev59.com/C5gtH.webp)
接下来添加这个root.columnconfigure(0, weight=1)
:
![enter image description here](https://istack.dev59.com/ITGGK.webp)
接下来添加这个root.columnconfigure(2, weight=1)
:
![enter image description here](https://istack.dev59.com/p57qK.webp)
正如您从上面的图片所看到的,根据您设置权重的行和列,行和列将相应地调整大小。我们通过上面的代码实现了将0行和2行以及0列和2列调整大小。而
第1行第1列
不会调整大小。这意味着我们放置在
第1行第1列
位置的任何内容都不会调整大小,而是保持相对于边界的位置不变。因为我们在
第1行第1列
位置设置了一个框架小部件,然后所有的小部件都在框架内,我们有效地将
第1行第1列
作为中心。
Tkinter有多少行和列取决于您告诉它要有多少。此外,它还会将没有任何内容(小部件)的行和列设置为零大小。这意味着只有具有内容(小部件)的行和列才会影响网格的大小。
假设我们有3行3列。根据我们如何填充它,它将改变所显示内容的大小。
在这个例子中,任何您看到
X
的地方都表示我们放置了以下行和列的某些内容。
在这个例子中,我们有一些位于(0,0),(1,1)和(2,2)的内容。
ROW
0 1 2
*-------*-------*-------*
| | | |
0 | X | | |
C | | | |
O *-------*-------*-------*
L | | | |
U 1 | | X | |
M | | | |
N *-------*-------*-------*
| | | |
2 | | | X |
| | | |
*-------*-------*-------*
在这个例子中,我们有一些位于(0,0)和(2,2)之间的东西。
0 2
*-------*-------*
| | |
0 | X | |
| | |
*-------*-------*
| | |
2 | | X |
| | |
*-------*-------*
在这个例子中,我们有一些位于 (1,0),(2,1) 和 (2,2) 的内容。
0 1 2
*-------*-------*-------*
| | | |
1 | X | | |
| | | |
*-------*-------*-------*
| | | |
2 | | X | X |
| | | |
*-------*-------*-------*
上述示例说明了根据您使用小部件填充的行和网格自动显示的内容。
至于像sticky这样的参数,它们用于管理每个小部件的行为。例如,如果我们告诉一个小部件填满给定的行/列中的所有空间,那么我们将使用sticky='nsew'。如果我们想要一个小部件在给定的行/列中水平拉伸但不垂直拉伸,我们将使用sticky='ew'表示东/西方向。请记住,sticky参数是用于grid()的。pack()几何管理器有它自己的参数。
有许多选项,您可以在此处找到它们的列表及其描述:
{{link1:对于grid()}}
{{link2:对于pack()}}
看下面的示例。此代码将始终在窗口中心设置标签和按钮,即使您调整窗口大小也是如此。这比place容易得多。
在几何管理器中,有许多有用的参数可用于实现您希望的任何行为或对齐方式。只需花些时间深入了解它。我知道place()
看起来像是最好的选择(我在刚开始时也是这么想的,直到Bryan纠正了这个观念:D),但实际上并不是。
import tkinter as tk
root=tk.Tk()
root.rowconfigure(0, weight=1)
root.rowconfigure(2, weight=1)
root.columnconfigure(0, weight=1)
root.columnconfigure(2, weight=1)
center_frame = tk.Frame(root)
center_frame.grid(row=1, column=1, sticky='nsew')
tk.Label(center_frame, text='Name/ID').grid(row=0, column=0)
tk.Label(center_frame, text='Password').grid(row=1, column=0)
tk.Button(center_frame, text='Enter').grid(row=2, column=1)
root.mainloop()
这是一个使用pack()
的示例。我发现grid()
是我的首选,但pack()
也可以实现许多功能。
import tkinter as tk
root=tk.Tk()
center_frame = tk.Frame(root)
center_frame.pack(expand=True)
tk.Label(center_frame, text='Name/ID').pack(side='top')
tk.Label(center_frame, text='Password').pack(side='top')
tk.Button(center_frame, text='Enter').pack(side='right')
root.mainloop()
grid
或pack
而不是place
。这样会给自己带来很多额外的工作。 - Bryan Oakleygrid()
和pack()
非常精确。你只是还不知道如何实现你想要的。这里和网络上有很多关于你问题的例子。 - Mike - SMTplace
对于最基本的布局来说肯定更容易学习,但如果您需要UI具有响应性,它很快就会变得非常复杂。 - Bryan Oakleygrid()
和pack()
设置和更改起来要容易得多和快捷得多。了解如何使用每个功能可以使事情尽可能精确,但我也许不应该说它们更精确。 - Mike - SMT