如何禁用 Tkinter 的 Treeview 列的手动调整大小?
How to disable manual resizing of Tkinter's Treeview column?
由于 I can't horizontally scroll Treeview column 似乎是 Tk/Tkinter 的限制,我想把它粘在框架上。
问题是用户可以手动调整 Treeview 列的大小,这会以某种方式弄乱我的界面。是否可以禁用此类功能?
注意列的大小 header。
用户可以拖动鼠标来调整列的大小。我想禁用它。
将minwidth
设置为某个值可以防止列缩小,但仍然可以将其调整为更大的宽度。我想我可以对改变宽度做出反应并将其恢复为原始状态,但必须有更好的方法来做到这一点。
我刚刚找到了一个不错的解决方案。您可以在鼠标点击到达小部件之前捕获鼠标点击,防止用户修改列宽。
def disableEvent(event):
return "break"
treeviewName.bind("<Button-1>", disableEvent)
如果您真的需要检查哪个小部件被按下,event.widget
包含被按下的小部件。
以下仅在 Windows 上测试过,其他 OS 可能会有所不同。
对于任何未来的读者,从 Tk 8.5 开始,Treeviews 有一个 identify_region
方法接受屏幕位置 (x,y) 并将 return 一个对应于 treeview 区域的字符串坐标占据.
其中一个 return 值是 "separator"。
我用它来捕获 auto-size 列分隔符上的 double-click 事件,但你也可以用它来捕获 single-click 事件并阻止它们。
例如:
def handle_click(event):
if treeview.identify_region(event.x, event.y) == "separator":
return "break"
#...
treeview.bind('<Button-1>', handle_click)
这样做的好处是 不会 渲染整个树视图被禁用——所以你仍然可以 select/expand/collapse 行,点击要排序的列标题等 -- 您将无法调整列的大小。
请注意,即使禁用调整大小,"double arrow" 光标 (⇔) 仍会出现。您还可以通过对 <Motion>
事件执行完全相同的操作来防止显示双箭头光标(绑定到它,检查它是否在分隔符上方,并阻止事件通过 returning 传播字符串 "break"
).
>>> sys.version
'3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)]'
>>> tkinter.TkVersion
8.6
您可以水平滚动树视图,当我重新调整列的大小(在运行时,向右拖动'off screen')时,xscrollbar 被激活,在创建滚动条和树视图后使用事件调整您代码中列的大小(更大),例如按下按钮(比如当树视图被填充时),否则 '.xview' 没有检测到任何东西
vsbx = tkinter.Scrollbar(root_search_stock, orient="horizontal")
vsbx.place(x= 40, y = 550, width = 1000)
tree = tkinter.ttk.Treeview(root_search_stock,\
columns=column_names,yscrollcommand=vsby.set,xscrollcommand=vsbx.set)
tree.place(x = 50, y = 300)
vsbx.config(command = tree.xview)
我会全力以赴 - 这是我发现的 dead-simple 解决方案,它可以防止用户调整 ttk Treeview 中所有列的大小(在本例中名为 'my_treeview'
):
my_treeview.bind('<Motion>', 'break')
怎么做?
通过将处理程序绑定到 '<Motion>'
事件并将其设置为 'break'
,将鼠标悬停在列分隔符上不再调出调整大小光标(所有鼠标移动事件都被有效禁用) .
Treeview 元素仍然可以像往常一样单击和滚动,并且设置列宽仍然按预期工作。
由于 I can't horizontally scroll Treeview column 似乎是 Tk/Tkinter 的限制,我想把它粘在框架上。
问题是用户可以手动调整 Treeview 列的大小,这会以某种方式弄乱我的界面。是否可以禁用此类功能?
注意列的大小 header。
用户可以拖动鼠标来调整列的大小。我想禁用它。
将minwidth
设置为某个值可以防止列缩小,但仍然可以将其调整为更大的宽度。我想我可以对改变宽度做出反应并将其恢复为原始状态,但必须有更好的方法来做到这一点。
我刚刚找到了一个不错的解决方案。您可以在鼠标点击到达小部件之前捕获鼠标点击,防止用户修改列宽。
def disableEvent(event):
return "break"
treeviewName.bind("<Button-1>", disableEvent)
如果您真的需要检查哪个小部件被按下,event.widget
包含被按下的小部件。
以下仅在 Windows 上测试过,其他 OS 可能会有所不同。
对于任何未来的读者,从 Tk 8.5 开始,Treeviews 有一个 identify_region
方法接受屏幕位置 (x,y) 并将 return 一个对应于 treeview 区域的字符串坐标占据.
其中一个 return 值是 "separator"。
我用它来捕获 auto-size 列分隔符上的 double-click 事件,但你也可以用它来捕获 single-click 事件并阻止它们。
例如:
def handle_click(event):
if treeview.identify_region(event.x, event.y) == "separator":
return "break"
#...
treeview.bind('<Button-1>', handle_click)
这样做的好处是 不会 渲染整个树视图被禁用——所以你仍然可以 select/expand/collapse 行,点击要排序的列标题等 -- 您将无法调整列的大小。
请注意,即使禁用调整大小,"double arrow" 光标 (⇔) 仍会出现。您还可以通过对 <Motion>
事件执行完全相同的操作来防止显示双箭头光标(绑定到它,检查它是否在分隔符上方,并阻止事件通过 returning 传播字符串 "break"
).
>>> sys.version
'3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)]'
>>> tkinter.TkVersion
8.6
您可以水平滚动树视图,当我重新调整列的大小(在运行时,向右拖动'off screen')时,xscrollbar 被激活,在创建滚动条和树视图后使用事件调整您代码中列的大小(更大),例如按下按钮(比如当树视图被填充时),否则 '.xview' 没有检测到任何东西
vsbx = tkinter.Scrollbar(root_search_stock, orient="horizontal")
vsbx.place(x= 40, y = 550, width = 1000)
tree = tkinter.ttk.Treeview(root_search_stock,\
columns=column_names,yscrollcommand=vsby.set,xscrollcommand=vsbx.set)
tree.place(x = 50, y = 300)
vsbx.config(command = tree.xview)
我会全力以赴 - 这是我发现的 dead-simple 解决方案,它可以防止用户调整 ttk Treeview 中所有列的大小(在本例中名为 'my_treeview'
):
my_treeview.bind('<Motion>', 'break')
怎么做?
通过将处理程序绑定到 '<Motion>'
事件并将其设置为 'break'
,将鼠标悬停在列分隔符上不再调出调整大小光标(所有鼠标移动事件都被有效禁用) .
Treeview 元素仍然可以像往常一样单击和滚动,并且设置列宽仍然按预期工作。