【问题标题】:In what cases Tkinter's grid() cannot be mixed with pack()?在什么情况下 Tkinter 的 grid() 不能与 pack() 混合使用?
【发布时间】:2019-05-02 05:03:52
【问题描述】:

我想消除奇怪的额外空间,当单独使用grid() 时,我的布局中似乎无法调整任何大小,但调用pack() 有时会使事情变得更糟:GUI 完全消失了!

我从@Bryan Oakley 那里读到了一些令人大开眼界的布局答案,例如:

When to use pack or grid layouts in tkinter?

Tkinter: grid or pack inside a grid?

但是当我开始写自己的东西时,我仍然经常遇到麻烦。

我的理解:

  1. 我必须有一个框架来填充root window,否则没有希望填充窗口中的额外空间,但是我单独调整小部件。
  2. 对于位于共同父级 Frame 内的所有子小部件,我必须使用 pack()grid(),但不能同时使用两者。
  3. 在框架中使用grid() 时,必须使用非零weight 参数指定Frame.grid_rowconfigure().grid_columnconfigure()。否则,什么都不会显示。
  4. 因此可以让主Frame 使用pack(),但它的直接子Frames 都使用grid();在网格上的每个子 Frames 中,我们可以 pack() 他们自己的子小部件。换句话说,我们可以通过“区域”或容器层次结构级别将grid()pack() 交错,但绝不要将它们混合在同一个容器中:唯一的限制。
  5. 通过仔细的权重设计,我可以在父级Frame 中填充一个水平空间,其中一个子级Frame 充满水平布局的小部件,例如,所有小部件都使用grid(sticky='nsew'),而子级Frame 使用pack(side='top', fill='both', expand=True)

如果我的理解是正确的,那么我永远无法弄清楚为什么 #5 不能为我工作,例如,在我的水平孩子 Frame 的右端总是有未使用的额外空间在主 Frame 内根窗口。

更新 2

我想通了。 #5 对我不起作用,因为我在使用 grid() 之前忘记在主 Frame 中指定 .grid_columnconfigure(0, weight=1)。我的错!结案。

更新

我在 macOS High Sierra 上,运行 python 3.6.4 Homebrew。

【问题讨论】:

  • 好吧,#1 是错误的 - 您可以在该框架中执行的任何操作都可以直接在根窗口中轻松完成。调试提示:(暂时)给你的框架一个不同的边框和/或背景颜色,这样你就可以准确地看到它们的范围是什么。让小部件占用空间的问题实际上通常是封闭框架不占用空间的问题。
  • @jasonharper 是的,我总是给我的框架上色,并在有/没有框架的情况下搞乱。也许是 macOS。
  • @kakyo: 不,packgrid 在 tkinter 支持的所有平台上行为相同。

标签: python tkinter


【解决方案1】:

在什么情况下 Tkinter 的 grid() 不能和 pack() 混合使用?

在所有情况下,您都不能将gridpack 用于具有共同主控的小部件。在 master 中,所有直接子节点必须使用相同的几何管理器。在整个应用程序中,您可以随意混合使用packgrid,只要您遵循一条规则,即不能将它们同时用于具有相同父级的小部件。

  1. 我必须有一个框架来填充根窗口,否则就没有希望填充窗口中的额外空间,但是我单独调整小部件。

这是不正确的。您无需使用框架即可轻松填充根窗口中的所有空间。

  1. 对于位于公共父框架内的所有子小部件,我必须使用 pack() 或 grid(),但不能同时使用。

没错。第三种选择是使用place,尽管它很少是最佳选择。

  1. 在 Frame 中使用 grid() 时,必须使用非零权重参数指定 Frame.grid_rowconfigure() 和 .grid_columnconfigure()。否则,什么都不会显示。

这不是真的——将行和列配置为具有非零权重不是强制性的。这通常是一种最佳做法,但并不是小部件显示所必需的。权重仅适用于grid 如何管理额外 空间。无论您是否使用权重,任何大小非零的小部件都应该出现。

  1. 因此可以让主框架使用 pack(),但它的直接子框架都使用 grid()

正确。

  1. 通过仔细的权重设计,我可以在父 Frame 中填充水平空间,并在子 Frame 中填充水平布局的小部件,例如,所有小部件都使用 grid(sticky='nsew'),而子 Frame 使用 pack (side='top', fill='both', expand=True)。

没错。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    • 2018-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多