Воспроизводимый на Python-3.6.4, который включает в себя Tk-8.6.6.

ython-2.7.14 x64, Tk-8.5.15 (в комплекте)

Хорошо задокументировано, что у виджета Treeview в Tk много проблем, и Tkinter, будучи тонкой оболочкой, мало что делает для их решения. Распространенной проблемой является получение Treeview в

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

 до желаемого размера, который вы хотите, и кэшируйте это значение в безопасном месте. Когда вы добавляете, редактируете или удаляете строку, вам нужно пройтись по столбцам и запросить их текущее значение ширины, и если оно больше, чем ваша кэшированная ширина, установитеwidth вернуться к исходному кешированному значению иwidthтакже установлен к текущей ширине столбца. Последний столбец нуждается в своемminwidth свойство также установлено в «True», поэтому оно может использовать оставшееся пространство. Это активирует горизонтальную полосу прокрутки и позволяет ей соответствующим образом перемещать содержимое древовидной структуры, не изменяя ширину всего виджета.stretchБудьте осторожны

какой-то моментТк внутренне сбрасывает в равнойwidth, но делаетminwidthне вызвать перерисовку прямо сейчас. Позже вы удивитесь, когда вы измените виджет, например, добавив или удалив строку, поэтому вам придется повторять вышеизложенное каждый раз, когда виджет изменяется. Это не очень большая проблема, если вы поймете все места, где может произойти перерисовка.проблема


Изменение свойства стиля Ttk вызывает принудительную перерисовку всего приложения, поэтому появляется предупреждение, о котором я упоминал выше, виджет Treeview расширяется по горизонтали, и горизонтальная полоса прокрутки деактивируется.

Прохождение


Код ниже демонстрирует:

Полученное окно будет выглядеть примерно так:

# imports
from Tkinter import *
from ttk import *
from tkFont import *

# root
root=Tk()

# font config
ff10=Font(family="Consolas", size=10)
ff10b=Font(family="Consolas", size=10, weight=BOLD)

# style config
s=Style()
s.configure("Foo2.Treeview", font=ff10, padding=1)
s.configure("Foo2.Treeview.Heading", font=ff10b, padding=1)

# init a treeview
tv=Treeview(root, selectmode=BROWSE, height=8, show="tree headings", columns=("key", "value"), style="Foo2.Treeview")
tv.heading("key", text="Key", anchor=W)
tv.heading("value", text="Value", anchor=W)
tv.column("#0", width=0, stretch=False)
tv.column("key", width=78, stretch=False)
tv.column("value", width=232, stretch=False)
tv.grid(padx=8, pady=(8,0))

# init a scrollbar
sb=Scrollbar(root, orient=HORIZONTAL)
sb.grid(row=1, sticky=EW, padx=8, pady=(0,8))
tv.configure(xscrollcommand=sb.set)
sb.configure(command=tv.xview)

# insert a row that has data longer than the initial column width and
# then update width/minwidth to activate the scrollbar.
tv.insert("", END, values=("foobar", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"))
tv.column("key", width=78, stretch=False, minwidth=78)
tv.column("value", width=232, stretch=True, minwidth=372)


Обратите внимание, что горизонтальная полоса прокрутки активна, и что последний столбец за границей виджета слегка переполнен. Последние два звонка


 это то, что позволяет, но сбросив свойства столбца последнего столбца, мы видим, что Tk молча обновилtv.column а такжеwidth быть таким же:minwidthизменения

tv.column("value")
{'minwidth': 372, 'width': 372, 'id': 'value', 'anchor': u'w', 'stretch': 1}


Любые собственностьюЛюбые Стиль вызовет принудительную перерисовку виджета. Например, следующая строка устанавливает цвет на красный для производного класса стилей Checkbutton:foregroundТеперь это виджет Treeview:

s.configure("Foo2.TCheckbutton", foreground="red")


Проблема сейчас


сокращение весь виджет обратно. Последний столбец можно вернуть к его первоначальному размеру, установив к первоначально кэшированному размеру,width на «Ложь» иstretch до максимального размера столбца:minwidthНо ширина виджета Treeview не уменьшилась.

tv.column("value", width=232, stretch=False, minwidth=372)

Я нашел два возможных решения, оба в привязке к


 событие, используя последний отображаемый столбец:<Configure>Укажите смену темы:

Скрыть и повторно показать:

tv.column("value", width=232, stretch=True, minwidth=372)
tv.event_generate("<<ThemeChanged>>")

Оба работают, потому что они являются единственными способами, которые я могу найти, чтобы вызвать внутреннюю функцию Tk

tv.grid_remove()
tv.column("value", width=232, stretch=True, minwidth=372)
tv.grid()


, Первый работает потому чтоTtkResizeWidget() вызывает полный пересчет геометрии виджета, в то время как второй работает, потому что Treeview вызовет<<ThemeChanged>> если он не отображается, когда столбец переконфигурирован.TtkResizeWidget()Недостатком обоих методов является то, что иногда вы можете увидеть, как окно расширяется на один кадр, а затем сжимается обратно. Вот почему я считаю неоптимальным и надеюсь, что кто-то еще знает о лучшем подходе. Или, по крайней мере, связываемого события, которое происходит либо раньше

 или до того, как произойдет расширение, из которого я могу использовать один из вышеуказанных методов с.<Configure>Некоторые ссылки, указывающие, что это было проблемой в Tk для


долго время:Проблемы Treeview с горизонтальной полосой прокрутки на

Tcl Wiki (ищи).[ofv] 2009-05-30Проездной билет# 3519160Сообщение. на Tkinter-обсудить список рассылки.И проблема в том,

Все еще Воспроизводимый на Python-3.6.4, который включает в себя Tk-8.6.6.Принудительное изменение размера виджета Tkinter.ttk Treeview после уменьшения ширины его ст

Ответы на вопрос(0)

Ваш ответ на вопрос