2017-12-07 9 views
2

나는 ttk.Notebook이고 각 탭에는 ttk.Treeview이 있습니다. 모든 트리보기에는 동일한 열이 있지만 아래 코드와 같이 다른 항목이 포함되어 있습니다.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() 

모든 나무가 항상 동일한 열 너비를 갖기를 바랍니다. 예를 들어, 사용자가 열의 크기를 tree1으로 변경하면 tree2의 열 'a'도 크기를 조정해야합니다.

나는 열의 크기를 tree1.column('a', 'width')으로 얻을 수 있고 tree2.column('a', width=300)으로 설정할 수 있음을 알고 있습니다.

하지만 열의 크기가 변경된 것을 어떻게 감지합니까?

트리보기 <Configure> 이벤트가 열 크기 조정에 의해 트리거되지 않았 음을 확인했습니다.

+2

당신이 사용자 상호 작용을 단지 관심이 있다면, 당신은 다시''이벤트에 전화를 결합하고'identify_region (event.x, event.y)를'확인할 수 있습니다. 'separator '를 반환하면'identify_column (event.x)'와 그 이후의'width'를 통해 열의'iid'를 얻습니다. 지정된 너비로 지정된 위젯의 모든 열을 반복하는 함수를 만듭니다. 프로그래밍 방식으로'width'를 변경하면 - 그 함수를 호출하십시오. 사용자를 통해 변경된 경우 - ''이 처리해야합니다. – CommonSense

+1

그래, 좋은 생각 같아. 그러나 성능에 얼마나 타격을 입히고 트리 뷰 (treeview)가 얼마나 힘들 겠는지는 모르겠다. 분명히 구현에 달려있다. 그러나 또 다른 옵션은 같은 로직으로''에 바인딩하여 가능한 성능 문제를 방지하는 것입니다. – CommonSense

+0

'ttk :: treeview :: Press'로이 문제를 해결하는 것은 흥미로울 것입니다. – Nae

답변

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)) 너무 빨리 열 구분 기호를 이동하는 경우 위의 방법이 작동하지 않는 것을 깨달았다. 그래서 나는 다른 방법을 찾았습니다 : 사용자가 탭을 변경하면 현재 탭의 각 열 너비가 이전에 표시되는 탭의 해당 열 너비로 설정됩니다.

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