Update:
Turns out we can bind '<ButtonRelease-1>'
to the treeview as noted on this post: how-to-detect-resizing-of-ttk-treeview-column that @stovfl has pointed out in the comments. So I have updated my answer with less overhead :D.
I created a method that will check to see of the column width has changed and then if it has then calculate each row to see if we need to add ...
to the end.
This is accomplished with ImageFont
from PIL
thought for some reason there seams to be a size difference between Treeview font and PIL font. After some testing it appears that any font size you set in the style for the Treeview just add 5 to the PIL font and it should calculate correctly.
import tkinter as tk
import tkinter.ttk as ttk
from PIL import ImageFont
track_data = [[('This text is too long', 'Short text'), 'This text is too long'],
[('This text is toooooooo long', 'Short text'), 'This text is toooooooo long'],
[('This text is longer than most others', 'Short text'), 'This text is longer than most others'],
[('This text is short', 'Short text'), 'This text is short']]
def add_to_tree_list(long_text, short_text, top):
track_data.append([(long_text.get(), short_text.get()), long_text.get()])
top.destroy()
update_text()
def pop_list(ndex):
track_data.pop(ndex)
def remove_row_from_list():
top = tk.Toplevel(win)
build_top_frame(top)
update_text()
def build_top_frame(top):
row_button_list = []
for child in top.winfo_children():
child.destroy()
frame = tk.Frame(top)
frame.pack()
for ndex, sub_list in enumerate(track_data):
row_button_list.append([tk.Button(frame, text='Remove',
command=lambda n=ndex: (pop_list(n), update_text(), build_top_frame(top))),
tk.Label(frame, text='Row {}: {}'.format(ndex + 1, sub_list[1]))])
row_button_list[-1][0].grid(row=ndex, column=0)
row_button_list[-1][1].grid(row=ndex, column=1, sticky='w')
def top_for_new_row():
top = tk.Toplevel(win)
tk.Label(top, text='Add long text: ').grid(row=0, column=0)
tk.Label(top, text='Add short text: ').grid(row=1, column=0)
e1 = tk.Entry(top)
e2 = tk.Entry(top)
e1.grid(row=0, column=1)
e2.grid(row=1, column=1)
tk.Button(top, text='Submit', command=lambda: add_to_tree_list(e1, e2, top)).grid(row=2, column=0)
tk.Button(top, text='Cancel', command=top.destroy).grid(row=2, column=1)
def clear_and_load(data):
tree.delete(*tree.get_children())
for sub_list in data:
tree.insert('''''', 'end', text='L4', values=sub_list[0])
def update_text(_=None):
global old_col_width, old_track_data_len
col_width = tree.column('1')['width']
if col_width != old_col_width or old_track_data_len != len(track_data):
old_col_width = col_width
new_track_data = []
for text in track_data:
font = ImageFont.truetype("arial.ttf", 17)
size = font.getsize(text[0][0])
previous_long_text = ''
new_long_text = ''
if size[0] > col_width:
for char in text[0][0]:
new_long_text = '{}{}'.format(new_long_text, char)
new_size = font.getsize('{}{}'.format(new_long_text, '...'))[0]
if new_size < col_width:
previous_long_text = new_long_text
else:
new_track_data.append([('{}{}'.format(previous_long_text, '...'), text[0][1]), ''])
break
else:
new_track_data.append(text)
clear_and_load(new_track_data)
old_track_data_len = len(track_data)
win = tk.Tk()
win.columnconfigure(0, weight=1)
old_col_width = 200
old_track_data_len = 0
win.resizable(width=0, height=0)
style = ttk.Style()
style.configure('Treeview', font=('arial', 12))
tree = ttk.Treeview(win)
tree.grid(row=0, column=0)
tree.bind('<ButtonRelease-1>', update_text)
vsb = ttk.Scrollbar(win, orient='horizontal', command=tree.xview)
vsb.grid(row=1, column=0, sticky='nsew')
tree.configure(xscrollcommand=vsb.set)
vsb = ttk.Scrollbar(win, orient='vertical', command=tree.yview)
vsb.grid(row=0, column=1, sticky='nsew')
tree.configure(yscrollcommand=vsb.set)
btn_frame = tk.Frame(win)
btn_frame.grid(row=2, column=0, columnspan=2, sticky='ew')
btn_frame.columnconfigure(0, weight=1)
btn_frame.columnconfigure(1, weight=1)
tk.Button(btn_frame, text='Add Row!', command=top_for_new_row).grid(row=0, column=0, sticky='ew')
tk.Button(btn_frame, text='Remove Row!', command=remove_row_from_list).grid(row=0, column=1, sticky='ew')
columns = ('1', '2')
tree['columns'] = columns
tree['show'] = 'headings'
tree.column('1', width=200, stretch=True, anchor='w')
tree.column('2', width=100, anchor='w')
tree.heading('1', text='Col 1')
tree.heading('2', text='Col 2')
clear_and_load(track_data)
update_text()
win.mainloop()
Results:

Adding new line:

Removing lines:
