禁用树视图在更新后填充 window
Disable tree view from filling the window after update
我有非常简单的两列网格布局,其中第一列应显示一些文本,第二列显示树视图:
#! python3
from random import randint
import tkinter as tk
from tkinter import ttk
from tkinter.constants import *
class Application(ttk.Frame):
def __init__(self, root):
self.root = root
self.root.resizable(0, 0)
self.root.grid_columnconfigure(0, weight=1)
self.root.grid_columnconfigure(1, weight=3)
self.init_widgets()
self.arrange_grid()
def init_widgets(self):
self.text_frame = ttk.Labelframe(self.root, text='Info')
self.button = ttk.Button(self.root, text='Process', command=self.on_button)
self.tree = ttk.Treeview(self.root)
self.scroll = ttk.Scrollbar(self.root, orient=HORIZONTAL, command=self.tree.xview)
self.tree.configure(xscrollcommand=self.scroll.set)
def arrange_grid(self):
self.text_frame.grid(row=0, sticky=NSEW)
self.button.grid(row=0, sticky=N, pady=32)
self.tree.grid(row=0, column=1, sticky=NSEW)
self.scroll.grid(row=0, column=1, sticky=(S, W, E))
def on_button(self):
headers = list(range(20))
rows = [[randint(0, 100)] * len(headers) for i in headers]
self.tree["columns"] = headers
for i, row in enumerate(rows):
self.tree.insert("", i, values=row)
if __name__ == '__main__':
root = tk.Tk()
app = Application(root)
root.mainloop()
当我单击 "Process" 按钮时,树视图会填充数据,但同时它会调整根 window 的大小并填充整个 space.
如何指示 ttk 树视图在填充数据后保持其大小?
除非受到 window 的限制,否则树视图将增长以适应其所有列。 window 将增长以适应所有 children 除非你给它一个固定的大小。发生的事情是你给树视图很多列,导致它增长。因为它会增长,所以 window 会增长,因为您没有限制它的增长。
有几种解决方法。也许最简单的解决方案是将树放在一个框架中,这样您就可以为其指定明确的宽度和高度。这样做的关键是让框架控制其 children 的大小,而不是相反。这是通过关闭 几何传播 来完成的。
首先,首先创建一个框架,然后将树放入框架中。我们也可以将滚动条放在框架中,这样我们就可以将树和滚动条视为一个整体。
self.tree_frame = tk.Frame(self.root, width=400, height=200)
self.tree = ttk.Treeview(self.treeframe)
self.scroll = ttk.Scrollbar(self.tree_frame, orient=HORIZONTAL, command=self.tree.xview)
self.tree.configure(xscrollcommand=self.scroll.set)
接下来,将树视图和滚动条添加到框架中。您可以使用 pack
、place
或 grid
中的任何一个;我发现 pack
优于 top-to-bottom 布局。我们还使用 pack_propagate
来关闭几何传播(意思是:框架宽度和高度得到尊重):
self.tree_frame.pack_propagate(0)
self.scroll.pack(side="bottom", fill="x")
self.tree.pack(side="top", fill="both", expand=True)
因此,您需要修改 arrange_grid
以将框架放在根 window 中,然后忽略滚动条,因为它已经包含在框架中:
def arrange_grid(self):
self.text_frame.grid(row=0, sticky=NSEW)
self.button.grid(row=0, sticky=N, pady=32)
self.tree_frame.grid(row=0, column=1, sticky=NSEW)
注意:您已经关闭了用户调整 window 大小的功能。我建议避免这种情况——用户通常更清楚他们想要 window 的大小。相反,您应该将 GUI 配置为在用户调整 window.
大小时正确调整大小
由于您使用的是 grid
,您所要做的就是告诉 tkinter 哪些行和列会因用户调整 window 的大小而获得任何额外的 space。由于所有内容都在一行中,因此您只需要为该行赋予权重:
root.grid_rowconfigure(0, weight=1)
我有非常简单的两列网格布局,其中第一列应显示一些文本,第二列显示树视图:
#! python3
from random import randint
import tkinter as tk
from tkinter import ttk
from tkinter.constants import *
class Application(ttk.Frame):
def __init__(self, root):
self.root = root
self.root.resizable(0, 0)
self.root.grid_columnconfigure(0, weight=1)
self.root.grid_columnconfigure(1, weight=3)
self.init_widgets()
self.arrange_grid()
def init_widgets(self):
self.text_frame = ttk.Labelframe(self.root, text='Info')
self.button = ttk.Button(self.root, text='Process', command=self.on_button)
self.tree = ttk.Treeview(self.root)
self.scroll = ttk.Scrollbar(self.root, orient=HORIZONTAL, command=self.tree.xview)
self.tree.configure(xscrollcommand=self.scroll.set)
def arrange_grid(self):
self.text_frame.grid(row=0, sticky=NSEW)
self.button.grid(row=0, sticky=N, pady=32)
self.tree.grid(row=0, column=1, sticky=NSEW)
self.scroll.grid(row=0, column=1, sticky=(S, W, E))
def on_button(self):
headers = list(range(20))
rows = [[randint(0, 100)] * len(headers) for i in headers]
self.tree["columns"] = headers
for i, row in enumerate(rows):
self.tree.insert("", i, values=row)
if __name__ == '__main__':
root = tk.Tk()
app = Application(root)
root.mainloop()
当我单击 "Process" 按钮时,树视图会填充数据,但同时它会调整根 window 的大小并填充整个 space.
如何指示 ttk 树视图在填充数据后保持其大小?
除非受到 window 的限制,否则树视图将增长以适应其所有列。 window 将增长以适应所有 children 除非你给它一个固定的大小。发生的事情是你给树视图很多列,导致它增长。因为它会增长,所以 window 会增长,因为您没有限制它的增长。
有几种解决方法。也许最简单的解决方案是将树放在一个框架中,这样您就可以为其指定明确的宽度和高度。这样做的关键是让框架控制其 children 的大小,而不是相反。这是通过关闭 几何传播 来完成的。
首先,首先创建一个框架,然后将树放入框架中。我们也可以将滚动条放在框架中,这样我们就可以将树和滚动条视为一个整体。
self.tree_frame = tk.Frame(self.root, width=400, height=200)
self.tree = ttk.Treeview(self.treeframe)
self.scroll = ttk.Scrollbar(self.tree_frame, orient=HORIZONTAL, command=self.tree.xview)
self.tree.configure(xscrollcommand=self.scroll.set)
接下来,将树视图和滚动条添加到框架中。您可以使用 pack
、place
或 grid
中的任何一个;我发现 pack
优于 top-to-bottom 布局。我们还使用 pack_propagate
来关闭几何传播(意思是:框架宽度和高度得到尊重):
self.tree_frame.pack_propagate(0)
self.scroll.pack(side="bottom", fill="x")
self.tree.pack(side="top", fill="both", expand=True)
因此,您需要修改 arrange_grid
以将框架放在根 window 中,然后忽略滚动条,因为它已经包含在框架中:
def arrange_grid(self):
self.text_frame.grid(row=0, sticky=NSEW)
self.button.grid(row=0, sticky=N, pady=32)
self.tree_frame.grid(row=0, column=1, sticky=NSEW)
注意:您已经关闭了用户调整 window 大小的功能。我建议避免这种情况——用户通常更清楚他们想要 window 的大小。相反,您应该将 GUI 配置为在用户调整 window.
大小时正确调整大小由于您使用的是 grid
,您所要做的就是告诉 tkinter 哪些行和列会因用户调整 window 的大小而获得任何额外的 space。由于所有内容都在一行中,因此您只需要为该行赋予权重:
root.grid_rowconfigure(0, weight=1)