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.
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()))))
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()
Here is a screenshot of the running program:

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