下面是我想发送事件数据的弹出菜单命令。我想要事件的 x 和 y 数据,以便我知道要对 ttk 样式的树视图(用作表)的哪个单元格进行操作。目前它调用"self.toggle_sort_bool"方法,但我希望它在末尾调用函数"self.sort_children(event,cur_tree_children)",但不这样做,因为我需要弄清楚在这里传递/接收事件。注意:我知道发送是自动的,但接收不是。 我忽略了什么吗?
self.heading_popup_menu = tk.Menu(self.treeview, tearoff=0)
self.heading_popup_menu.add_command(label="Reverse Sort", command=self.toggle_sort_bool)
在这里,通过右键单击 ttk 样式的树视图,活动旅程开始。
self.treeview.bind('<Button-3>', self.pop_up_right_click_detail)
事件的x_root和y_root将发送到tk_popup。我应该/可以重载它以发送整个事件吗?似乎根中事件的 x 和 y 被发送以告诉弹出窗口在哪里......弹出。
def pop_up_right_click(self, event):
try:
self.heading_popup_menu.tk_popup(event.x_root, event.y_root, 0)
finally:
self.heading_popup_menu.grab_release()
这是我要从菜单命令调用的函数。
def sort_children(self, event, cur_tree_children):
region = self.treeview.identify("region", event.x, event.y)
if region == "heading":
#get column number
col = self.treeview.identify_column(event.x)
col = int(re.sub('D', '', col))
col_names = cur_tree_children.pop(0)
cur_tree_children.sort(reverse=self.reverse_sort_bool.get(), key=lambda tup: self.sort_disparate_types(tup[col-1])) #toggle reverse somehow
cur_tree_children.insert(0, col_names)
self.depopulate_tree()
self.populate_tree()
是否可以通过菜单发送事件?我很困惑,因为缺乏更好的术语,事件在通过右键单击弹出菜单调用函数时是多么脱节。虽然这都是一个大型 GUI 类的一部分,但我不想使用类实例变量来传达目标单元格数据,因为我认为这是混乱和不好的做法,因此应尽可能避免。
附言如果我有足够的声誉,我会制作标签BryanOakley并将其发布在它下面。
执行所需操作的常用方法是在显示菜单之前立即修改菜单命令。您可以定义postcommand
来定义在显示菜单之前运行的函数,也可以在导致菜单弹出的代码中进行修改。
由于您要将事件传递给函数,因此最好的解决方案是在弹出菜单之前立即修改菜单,因为该函数已经具有事件对象。
另一种选择是让您的函数设置一些实例变量,而不是修改菜单。然后,您可以在从菜单调用的函数中引用这些实例变量。
既然你说你不想使用实例变量,下面是一个演示如何修改菜单的示例:
def show_popup(self, event):
self.popup.entryconfig("Do Something", command=lambda: self.something(event))
self.popup.tk_popup(event.x_root, event.y_root)
例
这是一个完整的工作示例。该代码显示一个带有树视图小部件的窗口,该小部件具有一些虚拟数据。如果右键单击树视图,您将看到一个包含一个项目的菜单。当您单击该项目时,它将在标签中显示有关单击发生位置的信息。
import tkinter as tk
from tkinter import ttk
class Example(object):
def __init__(self):
self.root = tk.Tk()
self.treeview = ttk.Treeview(self.root, columns=("one", "two", "three"))
self.label = tk.Label(self.root, width=40)
self.label.pack(side="bottom", fill="x")
self.treeview.pack(fill="both", expand=True)
self.popup = tk.Menu(self.root, tearoff=False)
self.popup.add_command(label="Do something")
self.treeview.bind('<Button-3>', self.show_popup)
for column in self.treeview.cget("columns"):
self.treeview.column(column, width=50)
for i in range(10):
values = ("a%s" % i, "b%s" %i, "c%s" %i)
self.treeview.insert('', 'end', text="Item %s" % i, values=values)
def start(self):
self.root.mainloop()
def show_popup(self, event):
self.popup.entryconfig("Do something", command=lambda: self.do_something(event))
self.popup.tk_popup(event.x_root, event.y_root)
def do_something(self, event):
region = self.treeview.identify("region", event.x, event.y)
col = self.treeview.identify_column(event.x)
message = "you clicked %s,%s region=%s column=%s" % (event.x, event.y, region, col)
self.label.configure(text=message)
if __name__ == "__main__":
Example().start()