【发布时间】:2018-12-27 11:37:44
【问题描述】:
我的情况是,我必须单独使用 .pack() 或 .grid() 来实现指定的小部件尺寸(当它们并排放置时)。
我曾经根据这篇文章中获得的知识将.pack() 与.grid() 混合使用:
In what cases Tkinter's grid() cannot be mixed with pack()?
即,将框架彼此相邻打包,但在每个框架内,我都有网格。它工作得很好,直到我在官方 Python 3.7.2 中将 Tcl/TK 后端升级到 8.6.8,当我开始看到解释器问题时:
_tkinter.TclError: cannot use geometry manager grid inside . which already has slaves managed by pack
然后我将所有内容切换到 .pack(),但现在我无法恢复我的列设计,其中一些小部件比其他小部件更宽。
我是否应该制作所有 .grid() 来实现这一点,或者 .pack() 中是否有我在文档中没有看到的秘密成分?
理想情况下,我希望实现以下目标
- 在一排widget中,widget彼此相邻并尽可能地填满空间,类似于
.pack(side='left', fill='x', expand=True) - 在同一行中,我仍然可以将一个小部件指定为比其他小部件更宽,这样在将所有内容设置为
expand=True时,相对尺寸仍然可以控制。
示例
在 macOS 上,以下代码为我提供了更宽的入口和更窄的滑块,而我希望反过来,只需 .pack()。
import tkinter as tk
import tkinter.ttk as ttk
root = tk.Tk()
mainframe = tk.Frame(root, bg='blue')
mainframe.pack()
row1 = tk.Frame(mainframe, bg='red')
entry = ttk.Entry(row1, text='Search...')
slider = ttk.Scale(row1)
btn1 = ttk.Button(row1, text='Reset')
btn2 = ttk.Button(row1, text='Help')
entry.pack(side='left', fill='x', expand=True)
slider.pack(side='left', fill='x', expand=True)
btn1.pack(side='left', fill='x', expand=True)
btn2.pack(side='left', fill='x', expand=True)
row1.pack()
root.mainloop()
我必须强调,我知道如何将.grid() 与使用.grid_columnconfigure(col, weight) 的“行”一起使用,这很有效。这只是我的工作代码(当然比上面的例子更复杂)在升级到 TK 8.6 后就崩溃了,这意味着随着我的项目变得越来越大,混合管理器将越来越难以维护。所以我决定在.pack() 和.grid() 之间选择一个阵营。如果一个人能够以一定的代价实现另一个人所能做到的一切,那就太好了。
【问题讨论】:
-
错误信息告诉你到底出了什么问题——你在根窗口中同时使用了grid和pack。正如您链接到的问题所说,您不能这样做。
-
@BryanOakley 是的。我的问题不在于这个,而是如何单独使用
.pack()的一行小部件来实现大小部分。我会相应地更新我的问题。 -
这个问题太模糊了。有很多方法可以进行布局,最好的方法高度依赖于你想要的行为。如果您在列中布置东西,通常(尽管并非总是),网格是最好的,因为这就是它的设计目的。尝试使用 pack 实现精确的列宽可能具有挑战性,尽管这在很大程度上取决于每列中的其他小部件。
-
我建议您通过对其进行编辑并向其添加足够多的代码来减少您的问题的模糊性,使其成为一个可运行的示例(即使它没有按照您想要的方式进行布局)。
-
@martineau 我用一个例子更新了这个问题。谢谢。