如何检测ttk.Treeview列的大小调整?

时间:2017-12-07 12:41:00

标签: python tkinter ttk

我有ttk.Notebook,每个标签都包含ttk.Treeview。所有树视图都具有相同的列,但包含不同的项目,如下面的代码所示。

import tkinter as tk
from tkinter import ttk

root = tk.Tk()

notebook = ttk.Notebook(root)
notebook.pack()

tree1 = ttk.Treeview(notebook, columns=['a', 'b', 'c'])
tree1.insert('', 'end', text='item1', values=('a1', 'b1', 'c1'))
tree2 = ttk.Treeview(notebook, columns=['a', 'b', 'c'])
tree2.insert('', 'end', text='item2', values=('a2', 'b2', 'c2'))
tree2.insert('', 'end', text='item2', values=('a2', 'b2', 'c2'))

notebook.add(tree1, text='Tab 1')
notebook.add(tree2, text='Tab 2')

root.mainloop()

我希望所有树都具有相同的列宽。因此,例如,当用户调整列的大小时,' a' tree1的列,' a'也应调整tree2的大小。

我知道我可以获得一个列的大小 tree1.column('a', 'width')并将其设置为tree2.column('a', width=300)

但是,如何检测列的大小是否已更改?

我已经检查过,树大小<Configure>事件不是由列大小调整触发的。

1 个答案:

答案 0 :(得分:1)

根据CommonSense的建议,我在<ButtonRelease-1>上建立了绑定,以检查列是否已调整大小。如果tree.identify_region(event.x, event.y)'separator',则会调整大小。然后我需要识别分隔符两侧的列。 tree.identify_column(event.x)'#<column number>'的形式向我提供了左侧的列,我可以从中获取右侧列的ID。 最后,我执行调整所有树中列的大小的函数。

import tkinter as tk
from tkinter import ttk

root = tk.Tk()


def on_click_release(event):
    tree = event.widget
    if tree.identify_region(event.x, event.y) == 'separator':
        left_column = tree.identify_column(event.x)
        right_column = '#%i' % (int(tree.identify_column(event.x)[1:]) + 1)
        width_l = tree.column(left_column, 'width')
        width_r = tree.column(right_column, 'width')
        for tree2 in trees:
            if tree2 != tree:
                tree2.column(left_column, width=width_l)
                tree2.column(right_column, width=width_r)


notebook = ttk.Notebook(root)
notebook.pack()

trees = [ttk.Treeview(notebook, columns=['a', 'b', 'c']) for i in range(4)]

for i, tree in enumerate(trees):
    tree.bind('<ButtonRelease-1>', on_click_release)
    notebook.add(tree, text='Tab %i' % i)

root.mainloop()

编辑:我意识到如果我们过快地移动列分隔符(tree.identify_region(event.x, event.y)没有返回&#39; separator&#39;),则上述方法不起作用。所以我找到了一个不同的方法:当用户更改选项卡时,当前选项卡的每列的宽度设置为先前可见选项卡的相应列的宽度。

import tkinter as tk
from tkinter import ttk


def tab_changed(event):
    global current_tab
    tab = notebook.index('current')  # get newly visible tab number
    tree1 = trees[current_tab]  # get previously visible tree
    tree2 = trees[tab]   # get newly visible tree
    cols = ('#0', ) + tree1.cget('columns')  # tuple of all columns
    for column in cols:
        tree2.column(column, width=tree1.column(column, 'width'))
    current_tab = tab


root = tk.Tk()
notebook = ttk.Notebook(root)
notebook.pack()

trees = [ttk.Treeview(notebook, columns=['a', 'b', 'c']) for i in range(4)]
current_tab = 0  # store currently visible tab number

for i, tree in enumerate(trees):
    notebook.bind('<<NotebookTabChanged>>', tab_changed)
    notebook.add(tree, text='Tab %i' % i)

root.mainloop()