当我右键单击菜单时,我想删除它。
通常用bind("Mouse3", deletefunction)
完成,但是我需要一个checkbutton的实际实例来绑定它,并且我知道的向菜单添加checkbutton的唯一方法是add_checkbutton()
方法(而且我没有以这种方式访问实例)。我有什么办法可以做到这一点?
import tkinter as tk
root = tk.Tk()
menubar = tk.Menu(root)
view_menu = tk.Menu(menubar, tearoff=0)
view_menu.add_checkbutton(label="Right click on me to delete", onvalue=1, offvalue=False)
# I want to do something like this:
# c = Checkbutton(label="Right click on me to delete")
# c.bind("Mouse3", my_delete_function())
# view_menu.add(c)
menubar.add_cascade(label='View', menu=view_menu)
root.config(menu=menubar)
root.mainloop()
答案 0 :(得分:1)
据我所知,您的问题基本上有两个部分:
菜单栏项目可以在以后分配吗?
然后可以将引用的项目绑定到事件吗?
第一个答案是。虽然无法精确分配对象,但您可以 通过索引引用它,如下所示:
view_menu.delete(0)
自从您首先添加checkbutton
以来,其索引为0。您可以跟踪索引,也可以通过其label
引用该项目。 See this related answer from Bryan Oakley。例如:
view_menu.delete(view_menu.index("Right click on me to delete"))
.index()
方法将通过菜单项的index
找到label
,这很方便,除非您多次拥有相同的标签...
第二个答案,据我所知,似乎对诸如鼠标单击之类的典型事件没有任何有效约束。但是,经过一些搜索,我确实遇到了至少触发一个事件的rather hidden <<MenuSelect>>
binding。 That by itself is not useful to your quest,但您可以将event state与checkbutton
的{{1}}参数以及布尔值标记结合使用,以触发点击事件:
command
注意:实际上,您必须按住右键单击,然后左键单击# Add a BooleanVar for flagging:
delete_checkbutton = tk.BooleanVar()
# Add a binding to your view_menu
view_menu.bind('<<MenuSelect>>', event_state)
# Define the callback function:
def event_state(e):
if bool(e.state & 0x0400): # watch for the Mouse Right click state
# you might opt to use 0x0004 or 0x0001 instead
# i.e. Ctrl+click or Shift+Click
delete_checkbutton.set(True)
else: # If the state is not right click, reset the flag
delete_checkbutton.set(False)
# Define a self_delete command for the checkbutton
def self_delete():
if delete_checkbutton.get():
view_menu.delete(view_menu.index("Right click on me to delete"))
# Add the command to your checkbutton
view_menu.add_checkbutton(label="Right click on me to delete", onvalue=lambda:print('hey'), offvalue=False, command=self_delete)
才能将其删除。显然,缺点是您现在已经触发了开/关值,并且可能需要对其进行一些其他处理。
如果右键单击太尴尬,则Ctrl / Shift是您可能会考虑的另一种mod状态。
另一点说明:关于checkbutton
,我是OOP的支持者,它使可访问变量和标志变得更加容易,而不必担心tkinter
和global
命名空间。在这里,由于nonlocal
是在delete_checkbutton
命名空间中设置的,因此我使用了global
关键字,并通过global
对象对其进行了访问。但是,如果您要使用python布尔值(例如tk.BooleanVar()
),那么除非您在两个函数中都指定flag = True
,否则它的效果将不那么理想。但是,如果您采用OOP方法,则可以直接通过global flag
毫无疑问地引用这些标志。
最后,以下是在代码中实施的全面更改以进行采样:
self.flag
所有,我认为这不是一个非常流畅的用户体验,并且有些令人困惑。仅仅永久删除菜单项最多是有问题的,再加上您尝试调用该删除方法时,您会感到更加人为。我建议您重新考虑您的UX流,以考虑如何简化它。