如何在缩小列宽后强制Tkinter.ttk Treeview组件重新调整尺寸
Oh man, I feel your pain—this Treeview horizontal scroll problem in Python 2.7.14 with the bundled Tk 8.5.15 is such a frustrating gotcha. When you're in browse mode, trying to get the scrollbar to play nice either results in your parent container getting stretched way too wide (thanks to summing up column widths) or the scrollbar just sitting there doing nothing. Let's break down a solid fix for this:
Core Issue Recap
By default, the Treeview's total width is the sum of all its column widths. Add too many columns, and it'll just blow out the parent container instead of triggering the horizontal scrollbar. We need to force the Treeview to respect the parent container's width while letting its internal content scroll horizontally.
Step-by-Step Solution
Here's a practical implementation that addresses the problem:
Wrap Treeview and Scrollbar in a Frame
Using a Frame as the parent container lets us control the visible area for the Treeview, ensuring it doesn't escape beyond the space we allocate.Link Scrollbar and Treeview Properly
Make sure the Treeview'sxscrollcommandis tied to the scrollbar'ssetmethod, and the scrollbar'scommandlinks back to the Treeview'sxviewmethod. This connects their behaviors.Dynamic Width Binding
Bind the container Frame's<Configure>event to adjust the Treeview's width dynamically. This ensures whenever the container resizes, the Treeview stays within bounds, and content beyond that triggers the scrollbar.
Working Code Example
import Tkinter as tk import ttk root = tk.Tk() root.title("Treeview Horizontal Scroll Fix") # Create a wrapping frame to contain the Treeview and scrollbar tree_container = tk.Frame(root) tree_container.pack(fill=tk.BOTH, expand=True, padx=8, pady=8) # Horizontal scrollbar setup horizontal_scroll = ttk.Scrollbar(tree_container, orient=tk.HORIZONTAL) horizontal_scroll.pack(side=tk.BOTTOM, fill=tk.X) # Treeview configuration (browse mode) tree = ttk.Treeview(tree_container, xscrollcommand=horizontal_scroll.set) tree.pack(side=tk.TOP, fill=tk.BOTH, expand=True) horizontal_scroll.config(command=tree.xview) # Set up columns (simulating a wide set of columns) column_names = ["Column {}".format(i) for i in range(1, 12)] tree["columns"] = column_names tree["show"] = "headings" # Enable browse mode by hiding the default tree column # Initialize column widths for col in column_names: tree.heading(col, text=col) tree.column(col, width=120) # Set initial column width # Bind container resize event to adjust Treeview width def adjust_tree_width(event): # Get the container's current width, use it to set Treeview's visible width container_width = tree_container.winfo_width() tree.configure(width=container_width) tree_container.bind("<Configure>", adjust_tree_width) # Add sample data to test scrolling for row_idx in range(6): row_values = ["Row {} - {}".format(row_idx, col) for col in column_names] tree.insert("", tk.END, values=row_values) root.mainloop()
Key Notes
- Browse Mode: Setting
show="headings"removes the default hierarchical column, which is essential for table-style browsing. - Dynamic Resizing: The
<Configure>event handler ensures the Treeview always fits within its container, so any column width adjustments that push total content width beyond the container will activate the scrollbar. - Tk 8.5 Quirks: In this version, double-check that the scrollbar and Treeview are properly linked—sometimes the
xviewmethod can be finicky if the bindings aren't set correctly.
内容的提问来源于stack exchange,提问作者Kumba




