我不确定之前是否曾经问过这个问题,因为它似乎太新了,但是我现在已经环顾了一个小时但没找到任何东西
我正在使用ttk Treeview来显示和分析表格。对于给定的函数,我希望能够识别双击(行和列)的确切单元格。虽然很容易找到行,但我找不到列,因为鼠标位置总是相对于屏幕显示,而不是相对于带有winfo_pointerx()的Treeview。我也无法让event.x工作......
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()
我非常感谢你的帮助。
您需要结合一些技巧来解决您的问题。
首先,您需要使用winfo_pointerxy()
。这将返回一个元组(x , y)
,其中包含相对于tree
根窗口的鼠标指针的坐标。
然后,您需要使用此元组的第一个元素winfo_pointerxy()[0]
来调用identify_column()
方法,从中减去winfo_rootx()
(以解决移动窗口的问题)。
但你需要小心,因为winfo_pointerxy()
返回的元组是<type 'unicode'>
类型。所以你需要,例如,import re
才能使用re.sub()
,这样你就可以将#1
形式的数据替换为整数1
。
这意味着你的filter()
方法现在看起来像这样:
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()))))
所以这是完整的程序:
'''
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()
以下是正在运行的程序的屏幕截图:
猜猜我找到了。问题是tree.winfo_pointerx()不返回相对于Treeview的位置,而是相对于屏幕。此外,tree.winfo_x()始终返回零。但是,从tree.winfo_pointerx()中减去self.root.winfo_x()可以完成这项工作。
在任何情况下,都需要重新转换坐标。
现在要走了,如果你需要一个片段,我会稍后发布。