Using this Python script, which is my first attempt to learn how ttk.Treeview
works (the extra copy of autoscroll is just to split the horizontal and vertical callbacks):
import Tkinter as tk
import ttk
class Test():
def __init__(self, parent=None):
self.win = tk.Toplevel()
self.win.grid_columnconfigure(0, weight=1)
self.win.grid_rowconfigure(0, weight=1)
self.treeFrame = ttk.LabelFrame(self.win, text='Test Scrolling tk.Treeview')
self.treeFrame.grid(row=0, column=0, padx=5, pady=5, sticky='nsew')
self.treeFrame.grid_columnconfigure(0, weight=1)
self.treeFrame.rowconfigure(0, weight=1)
def autoscrollv(sbar, first, last):
print 'vert first:%s, last:%s' % (first,last)
first, last = float(first), float(last)
if first <= 0 and last >= 1:
sbar.grid_remove()
else:
sbar.grid()
sbar.set(first, last)
def autoscrollh(sbar, first, last):
print 'horz first:%s, last:%s' % (first,last)
first, last = float(first), float(last)
if first <= 0 and last >= 1:
sbar.grid_remove()
else:
sbar.grid()
sbar.set(first, last)
vsb = ttk.Scrollbar(self.treeFrame, orient="vertical")
hsb = ttk.Scrollbar(self.treeFrame, orient="horizontal")
self.tree = ttk.Treeview(self.treeFrame, height=10,
yscrollcommand=lambda f, l: autoscrollv(vsb, f, l),
xscrollcommand=lambda f, l: autoscrollh(hsb, f, l))
self.tree.column("#0", minwidth=400, stretch=True)
vsb['command'] = self.tree.yview
hsb['command'] = self.tree.xview
self.tree.grid(row=0, column=0, sticky='nsew')
vsb.grid(column=1, row=0, sticky='ns')
hsb.grid(column=0, row=1, sticky='ew')
self.tree.insert('', 'end', 'xyz', text='abc'*20)
for i in range(30):
self.tree.insert('xyz', 'end', text='%s' % i + 'xyz'*40)
self.win.mainloop()
if __name__ == "__main__":
test = Test()
I see the following behavior: When I first run the program, the output looks like this:
.
If I expand the window until the horizontal scrollbar shuts off, it looks like this:
If I continue to expand the window, here is all the text shown:
My first question is, how can I get xscrollcommand
to recognize the actual width of the text, rather than using the value for minwidth
?
Going back to the state in the second image, if I open the item, it goes to this:
My second question is nearly the same as the first. How do I get it to recognize the new width of the item after it is opened?
If I change minwidth=400
to width=400
, the horizontal scrollbar never appears.
Summary: while the vertical scrollbar works as I would expect and reacts to the actual lines of text being displayed (rather than the ttk.Treeview
setting for height), the horizontal scrollbar only seems to care about the value for minwidth
. I thought of using something like below, especially if there is an equivalent for ttk
themed widgets. But, the setting for minwidth
doesn't take effect after populating the tree, although I can change the value for width at that point. Is there a way to force a change to minwidth
?
minwidth=tkFont.Font().measure(text)
self.tree.column('#0', minwidth=tcw)
Sorry for the extra window; that part of Tkinter confuses me no end...