Tkinter Treeview не дает указания для скрытых символов - PullRequest
4 голосов
/ 09 октября 2019

Текст «Это слишком длинный текст». Как вы можете видеть, в представлении есть возможность расширения по горизонтали, но нет указания на то, что в нем больше символов.

Мне нужно указать пользователю, что в ячейке больше символов. то есть показывает "...".

enter image description here

Это код:

from tkinter import ttk
import tkinter as tk

win = tk.Tk()
win.resizable(width=0, height=0)

tree = ttk.Treeview(win, selectmode='browse')
tree.grid(row=0, column=0)

vsb = ttk.Scrollbar(win, orient="horizontal", command=tree.xview)
vsb.grid(row=1, column=0, sticky=tk.W + tk.E + tk.N + tk.S)
tree.configure(xscrollcommand=vsb.set)

vsb = ttk.Scrollbar(win, orient="vertical", command=tree.yview)
vsb.grid(row=0, column=1, sticky=tk.W + tk.E + tk.N + tk.S)
tree.configure(yscrollcommand=vsb.set)

tree["columns"] = ("1", "2")
tree['show'] = 'headings'
tree.column("1", anchor='c')
tree.column("2", width=100, anchor='c')
tree.heading("1", text="Col 1")
tree.heading("2", text="Col 2")
tree.insert("", 'end', text="L4", values=("This text is too long","Short text"))

win.mainloop()

1 Ответ

3 голосов
/ 16 октября 2019

Обновление:

Оказывается, мы можем связать '<ButtonRelease-1>' с деревом, как отмечено в этом посте: как определить размер изменения ttk-treeview-column , что@stovfl указал в комментариях. Поэтому я обновил свой ответ с меньшими накладными расходами: D.

Я создал метод, который будет проверять, изменилась ли ширина столбца, а затем, если он, рассчитал каждую строку, чтобы увидеть, нужно ли добавить ... до конца.

Это достигается с помощью ImageFont из PIL, по какой-то причине кажется, что между шрифтом Treeview и шрифтом PIL есть разница в размерах. После некоторого тестирования выясняется, что любой размер шрифта, который вы установили в стиле Treeview, просто добавляет 5 к шрифту PIL, и он должен вычисляться правильно.

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()

Результаты:

enter image description here

Добавление новой строки:

enter image description here

Удаление строк:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...