Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Treeview mouse position python

I'm not really sure whether this question has been asked before, as it seems to be too trivial to be new, however I've been looking around for an hour now and have not found anything

I'm using ttk Treeview to display and analyze a table. For a given function I want to be able to identify the exact cell which has been double clicked (row and column). While it's easy to find the row, I can't find the column as the mouse position is always show relative to the screen, not relative to Treeview with winfo_pointerx(). Also I cannot get event.x to work...

from Tkinter import *
import ttk
import utils

class AudiDataList():

    def __init__(self, i_root, i_header, i_data, i_types):
        self.root = i_root

        f1 = ttk.Frame(root)
        f1.pack()
        t1 = ttk.Treeview(f1, columns=i_header, show="headings")
        t1.pack()

        for col in i_header:
            t1.heading(col, text=col.title())
        for item in i_data:
            t1.insert('', 'end', values=item, tags = ('item',))
        t1.tag_bind('item', "<Double-Button-1>", callback=lambda c=col: self.filter(t1, c, 0, i_types, i_header))

    def filter(self, tree, col, descending, i_types, i_header):
        print "Row: ", tree.focus()
        print "X-position", tree.winfo_pointerx()
        print "Column: ??? ",tree.identify_column(tree.winfo_pointerx())


header = ['col1', 'col2', 'col3']
datentypen = ['text', 'money', 'int']
data = [
('a', '1,00', 1) ,
('a', '2,00', 2) ,
('b', '12,10', 3) ,
('c', '2,10', 4) ,
('b', '3,00', 5)]

root = Tk()
Auditable = AudiDataList(root, header, data, datentypen)

root.mainloop()

I'd really appreciate your help.

like image 950
MartinM Avatar asked May 03 '26 13:05

MartinM


1 Answers

You need to combine few tricks to resolve your problem.

First, you will need to use winfo_pointerxy(). This returns a tuple (x , y) containing the coordinates of the mouse pointer relative to your tree 's root window.

You need then to use the first element of this tuple, winfo_pointerxy()[0], to call identify_column() method from which you substract winfo_rootx() (to resolve the problem of shifting the window).

But you need to be careful because the tuple returned by winfo_pointerxy() is of type <type 'unicode'>. So you will need, for example, to import re in order to use re.sub() so that you can replace data in form #1 to integer 1.

This means your filter() method will now look like this:

     def filter(self, tree, col, descending, i_types, i_header):               
         print 'Row: {} & Column: {} '.format(re.sub('I00','',str(tree.identify_row(tree.winfo_pointerxy()[1]-tree.winfo_rooty()))),re.sub(r'#','',str(tree.identify_column(tree.winfo_pointerxy()[0]-tree.winfo_rootx()))))

Full program

So here is the full program:

'''
Created on Apr 24, 2016

@author: billal begueradj
'''
from Tkinter import *
import ttk
import re

class AudiDataList():

    def __init__(self, i_root, i_header, i_data, i_types):
        self.root = i_root

        f1 = ttk.Frame(root)
        f1.pack()
        t1 = ttk.Treeview(f1, columns=i_header, show="headings")
        t1.pack()

        for col in i_header:
            t1.heading(col, text=col.title())
        for item in i_data:
            t1.insert('', 'end', values=item, tags = ('item',))
        t1.tag_bind('item', "<Double-Button-1>", callback=lambda c=col: self.filter(t1, c, 0, i_types, i_header))

         def filter(self, tree, col, descending, i_types, i_header):               
             print 'Row: {} & Column: {} '.format(re.sub('I00','',str(tree.identify_row(tree.winfo_pointerxy()[1]-tree.winfo_rooty()))),re.sub(r'#','',str(tree.identify_column(tree.winfo_pointerxy()[0]-tree.winfo_rootx())))) 

header = ['col1', 'col2', 'col3']
datentypen = ['text', 'money', 'int']
data = [
('a', '1,00', 1) ,
('a', '2,00', 2) ,
('b', '12,10', 3) ,
('c', '2,10', 4) ,
('b', '3,00', 5)]

root = Tk()
Auditable = AudiDataList(root, header, data, datentypen)

root.mainloop()

Demo

Here is a screenshot of the running program:

enter image description here

like image 185
Billal Begueradj Avatar answered May 05 '26 03:05

Billal Begueradj



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!