2017-07-10 76 views
1

私はpython 3を使用してtkinterでtreeviewを持っています。 問題は、右クリックした行の行IDを取得するために右クリックをバインドすると、直前のイベントの実際の行IDを取得します。たとえば、「Project 1」を右クリックすると「Project 2」を右クリックし、「Project 1」をrowIDとして返します。私はあなたが実際のROWIDを取得することができますので、そのIDと同じ各項目のタグを作るから成り汚いハックを見つけたTkinter右クリックイベントのTkinter Treeviewの識別結果は直前の右クリックされた行を返す

def initTreeView(self): 
    self.treeView = ttk.Treeview(self.treeSectionFrame) 
    self.treeView.heading('#0', text='Projects') 

    self.treeView.grid(row=0, column=0, sticky=("N", "S", "E", "W"))    


    self.treeView.bind('<3>', self.rightClickMenu) 

def rightClickMenu(self, event): 
    def hello(): 
     print("hello!") 
    # create a popup menu 
    print(event.x, event.y) 
    rowID = self.treeView.identify('item', event.x, event.y) 
    if rowID: 
     menu = Menu(self.root, tearoff=0) 
     menu.add_command(label="Undo", command=hello) 
     menu.add_command(label="Redo", command=hello) 
     menu.post(event.x_root, event.y_root) 

     self.treeView.selection_set(rowID) 
     self.treeView.focus_set() 
     self.treeView.focus(rowID) 
     print(rowID) 
    else: 
     pass 

おかげで、

[EDIT]

。これは、valueオプションを使用して行うこともできます。

... 
rowID = self.treeView.identify('item', event.x, event.y) 
print(rowID) 
... 

を...しかし、もちろん、これはあなたから期待しているものではありません。

self.treeView.insert("", "end", "id-1, tags="id-1", text="Project 1") 

... 
rowID = self.treeView.identify('item', event.x, event.y) 
rowID = self.treeView.item(rowID)["tags"] # gives you actual ID 

答えて

0

まず第一に、あなたが実際rowIDを印刷したい場合は、その後、ちょうどすぐにそれを印刷コード。この問題を克服するために - のロジックを少し反転してみましょう:あなたが見ることができるように

def rightClickMenu(self, event): 
    def hello(): 
     print("hello!") 
    # create a popup menu 
    print(event.x, event.y) 
    rowID = self.treeView.identify('item', event.x, event.y) 
    if rowID: 
     self.treeView.selection_set(rowID) 
     self.treeView.focus_set() 
     self.treeView.focus(rowID) 
     print(rowID) 

     menu = Menu(self.root, tearoff=0) 
     menu.add_command(label="Undo", command=hello) 
     menu.add_command(label="Redo", command=hello) 
     menu.post(event.x_root, event.y_root) 
    else: 
     pass 

、今変更選択はMenuウィジェットによってブロックされていません。

postの方法はすぐにMenuと表示され、このイベントはどうにかしてtkで処理する必要があるためです。したがって、我々は主な問題を抱えています:その位置は、postです。

別のアプローチ例:

... 
    menu = Menu(self.root, tearoff=0) 
    menu.add_command(label="Undo", command=hello) 
    menu.add_command(label="Redo", command=hello) 

    self.treeView.selection_set(rowID) 
    self.treeView.focus_set() 
    self.treeView.focus(rowID) 
    print(rowID) 
    menu.post(event.x_root, event.y_root) 
    ... 

しかし、私の意見では、私はここで最も論理的に正しいオプションは、別の関数に取り扱い選択を抽出し、Menupostcommand引数としてそれを使用することであると思います。それでは、1つのコールバック機能を使って同時に2つの椅子に座っているわけではありません。

+0

ありがとうございます。どのようにそれを反転させると、それは機能するのですか? –

+0

@私はLegendです。イベントキューに何らかのオーバーラップがあります(私はそれを前提としています)。メニューが表示されている間にユーザーがメニューとやり取りでき、コード実行がブロックされているため、 'tkinter'がmainloopに戻ります。とにかく私は私の答えを若干更新しました。 – CommonSense

関連する問題