【问题标题】:tkinter with Tcl/TK 8.6: Achieve "column widths" using pack()tkinter 与 Tcl/TK 8.6:使用 pack() 实现“列宽”
【发布时间】: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() 中是否有我在文档中没有看到的秘密成分?

理想情况下,我希望实现以下目标

  1. 在一排widget中,widget彼此相邻并尽可能地填满空间,类似于.pack(side='left', fill='x', expand=True)
  2. 在同一行中,我仍然可以将一个小部件指定为比其他小部件更宽,这样在将所有内容设置为 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 我用一个例子更新了这个问题。谢谢。

标签: python tkinter geometry


【解决方案1】:

使用pack,不可能让某些小部件比其他小部件扩展得更多。他们要么扩大,要么不扩大。如果您想保持相对比例,您必须将每个小部件强制为特定大小并仅让一个小部件展开,或者您需要使用 pack 以外的其他内容。

由于不清楚您想要实现什么,并且您声称已经使用grid 找到了可行的解决方案,因此我建议您坚持使用网格。您似乎已经在使用pack 作为根窗口。一个简单的解决方案是创建一个框架,您可以使用pack 添加到根目录,然后使用grid 将小部件放入框架内。

【讨论】:

    【解决方案2】:

    就个人而言,我会在 .grid() 中做所有事情,因为它比 .pack() 更容易维护,而且一旦事情变得复杂,它也更简单。前一段时间我用过 pack,我花了很长时间才完成工作,因为事情最终到了我不想要的地方。 有关网格列大小的更多信息:http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/grid-config.html 和 Tkinter configure columnwidth

    附:如果您想制作 GUI,那么有一个名为 Kivy 的库非常适合这类东西,如果您有兴趣,请查看 (https://kivy.org/#home),否则请使用网格。

    【讨论】:

    • 感谢您的想法。我知道 Kivy、Qt、wx 等。其中许多都是很好的解决方案。现在,我很想使用 Python 运行时的库存解决方案来轻松分发。
    猜你喜欢
    • 2016-01-31
    • 1970-01-01
    • 2017-12-02
    • 2021-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多