首页 > 解决方案 > Tkinter:标签和按钮框架之间的空间太大

问题描述

我对 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()

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

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

标签: pythonpython-3.xtkinter

解决方案


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

我建议让您的每个辅助函数返回框架,而不是调用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 右侧的顶部。

截屏


推荐阅读