I previously found本机菜单存在一些限制,我不满意(也就是说,它们窃取了很多事件而且不会共享)。
Bryan Oakly suggested我编写自己的菜单类,可以共享本机菜单窃取的事件。我想通过在无特征的Listbox
上加Toplevel
来做到这一点。 Menu
中没有内置于Listbox
的{{1}}期望的行为之一就是让鼠标悬停在项目上时突出显示项目。
以下是我为实现此目的而编写的代码:
import Tkinter as tk
class Menu(tk.Listbox):
def __init__(self, master, items, *args, **kwargs):
tk.Listbox.__init__(self, master, exportselection = False, *args, **kwargs)
self.pack()
for item in items:
self.insert(tk.END, item)
self.bind('<Enter>', lambda event: self.snapHighlightToMouse(event))
self.bind('<Motion>', lambda event: self.snapHighlightToMouse(event))
self.bind('<Leave>', lambda _: self.unhighlight())
def snapHighlightToMouse(self, event):
self.selection_clear(0, tk.END)
self.selection_set(self.nearest(event.y))
def unhighlight(self):
self.selection_clear(0, tk.END)
m = Menu(None, ['Alice', 'Bob', 'Caroline'])
tk.mainloop()
这种作品。有时突出显示在光标后面。有时似乎没有特别的原因卡住了。它并不一致,但我发现让它卡住的最可靠的方法是从左侧或右侧进入Caroline,然后向上移动到Bob和/或Alice - Caroline仍将是突出显示的项目。
同样,从顶部进入通常不会触发Enter事件 - Alice不会突出显示(其他人也不会突出显示)。
我有什么问题吗?有什么我可以做的事情可以更加可靠地跟随鼠标光标吗?
保持似乎始终触发而不失败 - 只是动作和输入被击中或错过。
答案 0 :(得分:0)
值得注意的是,绑定事件时会将事件传递给被调用的函数,因此您可以更改代码以删除lambdas,如下所示:
import Tkinter as tk
class Menu(tk.Listbox):
def __init__(self, master, items, *args, **kwargs):
tk.Listbox.__init__(self, master, exportselection = False, *args, **kwargs)
self.pack()
for item in items:
self.insert(tk.END, item)
self.bind('<Enter>', self.snapHighlightToMouse)
self.bind('<Motion>', self.snapHighlightToMouse)
self.bind('<Leave>', self.unhighlight)
def snapHighlightToMouse(self, event):
self.selection_clear(0, tk.END)
self.selection_set(self.nearest(event.y))
def unhighlight(self, event=None):
self.selection_clear(0, tk.END)
m = Menu(None, ['Alice', 'Bob', 'Caroline'])
tk.mainloop()
我知道严格来说,这并不能解决您的问题,但可能会使您的代码过于复杂/瘫痪,并且不会轻易放入评论中。我无法访问Mac,但值得一试。