Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to disable manual resizing of Tkinter's Treeview column?

Since I can't horizontally scroll Treeview column due to what appears to be Tk/Tkinter limitation, I want to make it sticky so it is attached to the frame.

The issue is that user can manually resize Treeview column which can mess up my interface in a certain way. Is it possible to disable such functionality?

Note the size of column header.

Note the size of the column header.

User can drag mouse to resize column. I want to disable this.

User can drag mouse to resize column. I want to disable this.

Setting minwidth to a certain value prevents column from shrinking, but it is still possible to resize it to a larger width. I suppose I can react to changing width and just revert it to original, but there has to be a better way to do it.

like image 588
Doom8890 Avatar asked Jul 27 '17 18:07

Doom8890


People also ask

How do I set Treeview size?

To set the row height of the Treeview widget, you can create an instance of ttk themed widget where you can specify the rowheight property. The rowheight property will add internal padding to each row in the table.

How do I disable Treeview in Python?

The Treeview widget is used to display a list of items with more than one feature in the form of columns. By default, the listed items in a Treeview widget can be selected multiple times, however you can disable this feature by using selectmode="browse" in the Treeview widget constructor.

How do you change column width in Treeview?

To configure the column width of the Treeview widget, we can use the width and stretch property. It sets the width of the Treeview widget column with the given value.

What is IID in Treeview?

The iid argument stands for item identifier which is unique for each item, and you can give it the value you want.


2 Answers

The following has only been tested on Windows, other OS's may vary.

For any future readers, since Tk 8.5, Treeviews have an identify_region method that accepts a screen position (x,y) and will return a string corresponding to the region of the treeview those coordinates occupy.

One of the return values is "separator".

I've used this to catch double-click events on the separator to auto-size columns, but you could also use it to catch single-click events and block them.

For example:

def handle_click(event):
    if treeview.identify_region(event.x, event.y) == "separator":
        return "break"

#...

treeview.bind('<Button-1>', handle_click)

This has the advantage of not rendering the entire treeview disabled -- so you can still select/expand/collapse rows, click column headings to sort, etc -- you just won't be able to resize the columns.

Note that even though resizing is disabled, the "double arrow" cursor (⇔) will still appear. You could additionally prevent the double arrow cursor from showing by doing the exact same thing with the <Motion> event (binding to it, checking if it's above a separator, and stopping the event from being propagated by returning the string "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
like image 53
jedwards Avatar answered Sep 30 '22 12:09

jedwards


I just found a decent solution. You can capture the mouse click before it reaches the widget, preventing the user to modify the column width.

def disableEvent(event):
    return "break"

treeviewName.bind("<Button-1>", disableEvent)

In case you need to really check which widget was pressed the event.widget contains the widget that was pressed.

like image 36
Kobbe Avatar answered Sep 30 '22 13:09

Kobbe