【问题标题】:tkinter - understand pack and grid - simple layout. (always confused...)tkinter - 了解包和网格 - 简单的布局。 (总是迷茫……)
【发布时间】:2020-10-08 09:12:21
【问题描述】:

我正在尝试配置一个文本框和文本框下方的 3 个按钮在一行居中 我不想扩大它们以填充所有区域。只是在中心保持原来的大小。

我试图用包或网格来做到这一点。但我真的很困惑。我还尝试将文本框和按钮放在不同的框架上,这样也许它会分开小部件并让我配置它而不会弄乱东西(因为一切都是相对于另一个......)......但我什么都没有这看起来不错。

我还想学习如何以正确的方式使用网格,如果我有各种小部件和按钮,一个在另一个之下,没有“列跨度”,或者调整按钮内的文本长度以匹配它们上面的小部件...

在这个例子中。我怎样才能使按钮居中?我必须使用 side=tkinter.LEFT 才能将它们一个接一个地放置。但是他们也坚持向左的问题......

import tkinter

window = tkinter.Tk()

frame1 = tkinter.Frame(window).pack()

textbox1 = tkinter.Text(frame1, width=70, height=15).pack(side=tkinter.TOP)

button1 = tkinter.Button(frame1, text="button1").pack(side=tkinter.LEFT)
button2 = tkinter.Button(frame1, text="button2").pack(side=tkinter.LEFT)
button3 = tkinter.Button(frame1, text="button3").pack(side=tkinter.LEFT)

window.mainloop()

在这个例子中,如果我设置另一个框架来分隔小部件...... 它也没有到达中心......

import tkinter

window = tkinter.Tk()

frame1 = tkinter.Frame(window).pack(side=tkinter.TOP)

textbox1 = tkinter.Text(frame1, width=70, height=15).pack(side=tkinter.TOP)

frame2 = tkinter.Frame(window).pack(side=tkinter.TOP)

button1 = tkinter.Button(frame2, text="button1").pack(side=tkinter.LEFT)
button2 = tkinter.Button(frame2, text="button2").pack(side=tkinter.LEFT)
button3 = tkinter.Button(frame2, text="button3").pack(side=tkinter.LEFT)

window.mainloop()

在这个例子中。使用网格,如果我使用不同的框架,按钮只会跳到文本框上并搞砸一切......

import tkinter

window = tkinter.Tk()

frame0 = tkinter.Frame(window).grid(row=0, column=0)

frame1 = tkinter.Frame(window).grid(row=1, column=0)

textbox = tkinter.Text(frame0, width=70, height=15).grid(row=0, column=0)

button1 = tkinter.Button(frame1, text="button1").grid(row=0, column=0)
button2 = tkinter.Button(frame1, text="button2").grid(row=0, column=1)
button3 = tkinter.Button(frame1, text="button3").grid(row=0, column=2)

window.mainloop()

有人可以向我解释一下哪种方式更好使用以及如何更好地理解它......? 它总是让我感到困惑......

提前致谢, 伊莱兰

【问题讨论】:

标签: python button tkinter textbox widget


【解决方案1】:

我以前也遇到过这类问题。尽管.pack().grid() 系统非常出色,但当事情变得忙碌时,您可以使用.place() 系统。 .place() 允许您使用 x-y 轴坐标精确定位您的 tkinter 和 ttk 小部件。

坐标 (0,0) 不在中心,而是在 tkinter 窗口的最左上角。

例如:

some_widget_name = Button(root, text="Click me!"....)
some_widget_name.place(x=100, y=50)

这将使您的小部件从最左上角向右移动 100 像素并向下移动 50 像素。

但是,有时当您真的想要使小部件的位置精确时,您可能需要进行一些反复试验才能使其在视觉上令人愉悦。

【讨论】:

  • 感谢您的重播。!是的,当我在画布上放置一些 png 图像时,我已经使用了 .place(),这很棒.. 但问题是当你想移动它们 \ 添加更多小部件到你的 gui 时,你必须再次使用坐标.. .而且你必须在视觉上进行(反复试验),因为很难预测它的位置,当你想做一些看起来准确的事情时非常令人沮丧。所以这就是为什么有时我想取消 .place()。我认为如果您真正提前计划界面的外观会更好。
【解决方案2】:

我试图用包或网格来做到这一点。但我真的很困惑。 我还尝试将文本框和按钮放在不同的位置 框架,所以它可能会将小部件分开并让我配置它 没有搞砸事情(因为一切都是相对于 其他......)......但我没有任何看起来不错的东西。

您的第二个示例非常接近工作,但它有一个致命的缺陷。如果添加一些调试语句,您会看到frame1frame2None。因此,任何以它们为父级的小部件实际上最终都会出现在根窗口中。

这是因为foo().bar() 总是返回.bar() 的结果。在 tkinter 中,.grid(...) 总是返回 None,所以 Frame(...).grid(...) 总是返回 None

最佳做法是始终将小部件创建与小部件布局分开。例如:

frame1 = tkinter.Frame(window)
frame2 = tkinter.Frame(window)

frame1.pack(side="top")
frame2.pack(side="top")

这样,frame1frame2 已正确设置为框架。发生这种情况时,第二个示例中的其余代码将按预期工作,并且按钮居中。

在这个例子中。使用网格,如果我使用不同的框架,按钮只会跳到文本框上并搞砸一切......

发生这种情况的原因与上面提到的相同:您认为您正在使用单独的框架,但一切都在根窗口中进行。因为它们都在根窗口中,并且您将文本小部件和按钮放在同一行和同一列中,所以它们重叠。

如果我有的话,我也想学习如何以正确的方式使用网格 各种小部件和按钮一个在另一个没有 “columnspan”或调整按钮内的文本长度以及 匹配它们上面的小部件...

grid 在这种特定情况下不是正确的选择,因为您实际上并没有创建网格。你可以使用它,但它比使用pack 需要更多的代码。如果您要创建实际网格,grid 是正确的选择。在这种情况下,你不是。

在这种情况下使用grid 需要一点创造力。虽然这不是唯一的解决方案,但我建议您将底部框架分为五列 - 左右各空一列,中间三列用于按钮。空列可用于占用所有额外空间,强制中间列全部居中。

使用grid 的最佳做法是,每个使用grid 管理其子窗口的窗口都需要至少一行和一列具有非零权重。这让 tkinter 知道在哪里分配任何额外空间,例如当用户调整窗口大小时。

这是使用grid的完整解决方案:

import tkinter

window = tkinter.Tk()

frame0 = tkinter.Frame(window)
frame1 = tkinter.Frame(window)

window.grid_rowconfigure(0, weight=1)
window.grid_columnconfigure(0, weight=1)

frame0.grid(row=0, column=0, sticky="nsew")
frame1.grid(row=1, column=0, sticky="nsew")

frame0.grid_rowconfigure(0, weight=1)
frame0.grid_columnconfigure(0, weight=1)

textbox = tkinter.Text(frame0, width=70, height=15)
textbox.grid(row=0, column=0, sticky="nsew")

button1 = tkinter.Button(frame1, text="button1")
button2 = tkinter.Button(frame1, text="button2")
button3 = tkinter.Button(frame1, text="button3")

frame1.grid_rowconfigure(0, weight=1)
frame1.grid_columnconfigure((0,4), weight=1)

button1.grid(row=0, column=1)
button2.grid(row=0, column=2)
button3.grid(row=0, column=3)

window.mainloop()

有人可以向我解释一下哪种方式更好用以及如何更好地理解它...?

总之,您使用单独框架的直觉是正确的起点。您应该将您的 UI 划分为逻辑组,并为每个组使用单独的框架。然后,您可以为每个组分别选择gridpack。但是,您需要谨慎使用 grid 以确保正确使用了 sticky 选项,并且您已为所有正确的列设置了权重。

最后,您必须从将小部件创建与小部件布局分开的正确做法开始。

【讨论】:

  • 哇。非常感谢您的详细解释。我会尝试更多地练习它 - 分离,重量和粘性......所有这些。您编写的完整解决方案正是我想要得到的。你说我在这个例子中并没有真正创建一个网格(什么是网格的正确定义)。我很高兴看到不同类型的布局示例更“容易”\“正确”使用。 pack() 和其他更适合选择使用 grid.() 的方法
猜你喜欢
  • 1970-01-01
  • 2020-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-05
  • 1970-01-01
  • 1970-01-01
  • 2018-03-30
相关资源
最近更新 更多