【问题标题】:Find position of another anchor than the anchor already used查找另一个锚点的位置,而不是已经使用的锚点
【发布时间】:2018-06-07 20:35:07
【问题描述】:

我创建了一个代码来显示我的问题。它看起来像这样:

userNameID = tkinter.Label(root, text="Name/ID")
userNameID.place(x=640, y=320, anchor="e")

userNameID = tkinter.Label(root, text="Password")
userNameID.place(x=640, y=360, anchor="e")

entButton = tkinter.Button(root, text="Enter", command=enterPrint)
entButton.place(x=640, y=400, anchor="w")

问题是我在中心的一个尺寸和另一侧的按钮上对齐了一些文本。我想知道文本的西北锚点的位置,以确保所有内容与中心的距离相同并且仍然对齐。

【问题讨论】:

  • 如果您刚刚学习 tkinter,我强烈鼓励您学习 gridpack 而不是 place。你为自己做了很多额外的工作。
  • 我曾尝试这样做,但不幸的是我发现它们“不精确”。有了无尽的网格,我无法理解。 pack 函数对我来说似乎没有任何参数,但我可能误解了一些东西。不过谢谢你,你在这个网站上的很多回答真的帮助了我
  • grid()pack() 非常精确。你只是还不知道如何实现你想要的。这里和网上有很多针对您的问题的示例。
  • 实际上,我认为 grid 和 pack 并不精确,这就是重点。您将小部件彼此相对放置,tkinter 会为您完成所有数学运算。您不应该关心标签以 100px 结尾并且条目从 120 开始,您应该只关心标签在左侧并且条目在右侧。 place 对于最基本的布局来说当然更容易学习,但如果你需要 UI 做出响应,它很快就会变成一个泥潭。
  • @BryanOakley 我想我的措辞可以使用一些工作。 grid()pack() 的设置和更改更容易、更快捷。知道如何使用每一种方法使事情变得像我曾经需要的那样精确,但我可能不应该说它们更精确。

标签: python python-3.x tkinter


【解决方案1】:

grid()pack() 是“精确的”,足以满足大多数需求。您只需要学习如何充分利用这些几何管理器。事实上,place() 的使用几乎不是您所需要的。它有其案例用途,但对于一般的 GUI 设置来说并不是一个很好的选择。更新代码也很难管理。

更新:在 cmets 中回答您的问题:

行配置的意思是因为权重你把每一行都设置为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()

结果:

在上面的示例中,您将看到小部件在调整窗口大小时不会移动。这是因为我们没有指示 tkinter 允许任何行或列移动。

如果我们将这个权重添加到程序root.rowconfigure(0, weight=1)

然后我们得到这个效果:

接下来添加这个root.rowconfigure(2, weight=1):

接下来添加这个root.columnconfigure(0, weight=1):

接下来添加这个root.columnconfigure(2, weight=1):

正如您在上面的图片中看到的,取决于您设置了权重的行和列,然后行和列将相应地调整大小。我们使用上面的代码实现的是调整第 0 行和第 2 行的大小以及调整第 0 和第 2 列的大小。 row 1 column 1 不会调整大小。所以这意味着我们放置在row 1 column 1 位置的任何东西都不会调整大小,而是保持其相对于边界的位置。因为我们在row 1 column 1 位置设置了一个框架小部件,然后我们在框架内的所有小部件都有效地使row 1 column 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' 表示东/西。请记住,粘性参数适用于grid()pack() 几何管理器有它自己的参数。

有很多选项,您可以在此处找到它们的列表及其描述:

For grid()

For pack()

以下面的例子为例。此代码将始终设置窗口的标签和按钮中心,即使您调整窗口大小也是如此。这比地方更容易管理。

您可以在几何管理器中使用许多有用的参数来实现您希望的任何行为或对齐。只是花时间去挖掘它。我知道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()

【讨论】:

  • "(place()) 有它的用例用例"......它的用例有哪些好的例子?因为确实“place() 几乎从来都不是你需要的”。
  • @ReblochonMasque 将图像直接添加到按钮并在不受 GUI 调整大小影响的应用程序上设置背景图像是我能想到的 2。也就是说,在我编程的这一年里,到目前为止,我只用过一次 place。
  • @ReblochonMasque:任何时候您需要放置具有绝对位置或相对于另一个小部件的小部件,并且不会影响或不受其他小部件影响。例如,添加图像作为框架或顶层的背景。为调整大小创建一点点。工具提示是另一个潜在用途。它对于创建 MDI(多文档界面,您在另一个窗口中有多个可独立移动的窗口)很有用。通用用途不多,但有几种特殊用途。
  • 谢谢各位先生(@Mike-SMT、@BryanOakley),您的回复很有帮助。
  • 非常感谢。我现在对一切都非常了解
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-09
  • 2016-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 2010-11-26
相关资源
最近更新 更多