【问题标题】:Tkinter: Too much space between label and button frameTkinter:标签和按钮框架之间的空间太大
【发布时间】:2020-03-19 13:31:25
【问题描述】:

我对 Tkinter 很陌生,我用不同的小部件构建了一个小窗口。

我的代码如下所示:

import tkinter as tk
from tkinter import ttk


class Application(tk.Frame):

    def __init__(self, master):
        super().__init__(master)
        self.master = master
        self.master.geometry("800x600")
        self.master.title("Tkinter Sandbox")
        self.master.grid_rowconfigure(0, weight=1)
        self.master.grid_columnconfigure(1, weight=1)

       self._create_left_frame()
       self._create_button_bar()
       self._create_label_frame()

    def _create_left_frame(self):
       frame = tk.Frame(self.master, bg="red")

       tree_view = ttk.Treeview(frame)
       tree_view.column("#0", stretch=tk.NO)
       tree_view.heading("#0", text="Treeview")
       tree_view.pack(fill=tk.Y, expand=1)
       frame.grid(row=0, column=0, rowspan=2, sticky=tk.N + tk.S)

    def _create_button_bar(self):
       frame = tk.Frame(self.master, bg="blue")

       button_run_single = tk.Button(frame, text="Button 1")
       button_run_all = tk.Button(frame, text="Button 2")
       button_details = tk.Button(frame, text="Button 3")
       button_run_single.grid(row=0, column=0)
       button_run_all.grid(row=0, column=1, padx=(35, 35))
       button_details.grid(row=0, column=2)
       frame.grid(row=0, column=1, sticky=tk.N)

    def _create_label_frame(self):
       frame = tk.Frame(self.master, bg="blue")

       name_label = tk.Label(frame, text="Label 1")
       performance_label = tk.Label(frame, text="Label 2")
       name_entry = tk.Entry(frame)
       performance_entry = tk.Entry(frame)
       name_label.grid(row=0, column=0)
       name_entry.grid(row=0, column=1)
       performance_label.grid(row=1, column=0)
       performance_entry.grid(row=1, column=1)
       frame.grid(row=1, column=1)


if __name__ == '__main__':
    root = tk.Tk()
    app = Application(root)
    app.mainloop()

三个按钮和标签+入口框之间是一个巨大的空间。我希望按钮和标签 + 输入框在彼此下方,没有巨大的空间,但树视图也应该在整个应用程序窗口中垂直扩展。

我认为问题可能是我的行和列配置,但我不知道如何解决这个问题。

【问题讨论】:

  • _button_barlabel_frame也使用right_frame

标签: python python-3.x tkinter


【解决方案1】:

您构建代码的方式很难看出问题所在。作为一个好的一般经验法则,对单个父级中的小部件的所有对 gridpack 的调用都应该在一个地方。否则,您会在难以查看和理解的函数之间创建依赖关系。

我建议让您的每个辅助函数返回框架,而不是在框架上调用 grid。这样你就可以控制Application.__init__ 来控制窗口主要部分的布局。

例如:

left_frame = self._create_left_frame()
button_bar = self._create_button_bar()
label_frame = self._create_label_frame()

left_frame.pack(side="left", fill="y")
button_bar.pack(side="top", fill="x")
label_frame.pack(side="top", fill="both", expand=True)

我在这里使用了pack,因为对于这种类型的布局,它比grid 需要更少的代码。但是,如果您选择切换到grid,或者希望稍后在根窗口中添加更多小部件,您只需修改这一个函数,而不是修改多个函数中的grid调用。

注意:这要求您的每个函数都执行return frame 以将帧传递回__init__ 方法。您还需要从每个辅助函数中删除 frame.grid

只需进行简单的更改,您就可以在右侧部分的顶部看到按钮栏和标签/条目组合。在以下屏幕截图中,我将 button_bar 的背景更改为绿色,以便您可以看到它填充了 UI 右侧的顶部。

【讨论】:

  • 哇,这是一个非常棒的解决方案,也是一个非常有用的提示。我将在我未来的项目中这样做。您是否知道一些资源或书籍,我可以在其中找到有关这些设计模式的最佳实践?
  • 嗨,布赖恩。最后一个问题。你能提供你的框架的源代码吗?我想再深入一点。
  • @NealMcBeal:“框架的源代码”是什么意思?你说的是什么框架?我使用的代码是问题中的代码,其中包含答案中描述的更改。
  • 很有趣,因为我更改了有关您的提案的代码,并且在标签部分的标签 1 和 2 中有不同的行为。它们居中。你知道为什么我不能在底部插入进度条吗?
  • @NealMcBeal:没有什么能阻止您在底部放置进度条。如果您在我的示例中使用pack,则应在 打包左右框架之前将其打包到底部。见stackoverflow.com/a/57396569/7432
【解决方案2】:

我更喜欢使用打包功能,因为它提供了一个更开放的窗口 - 易于配置。当您使用 Pack() 时,您可以使用不带文本和仅空格的标签来创建间隔,这样做您不会遇到您面临的问题。

【讨论】:

    【解决方案3】:

    你需要换行

    self.master.grid_rowconfigure(0, weight=1)
    

    self.master.grid_rowconfigure(1, weight=1)
    

    这样第二行就占据了所有空间。然后,您需要通过在_create_label_frame 中的网格调用中添加sticky 参数来将小部件从标签框架粘贴到其顶部:

    frame.grid(row=1, column=1, sticky=tk.N)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-03
      • 2022-01-19
      • 1970-01-01
      • 1970-01-01
      • 2022-10-19
      • 1970-01-01
      • 2018-08-05
      • 2020-09-23
      相关资源
      最近更新 更多