Python tkinter:“删除菜单”复选框

时间:2018-11-22 17:52:42

标签: python tkinter

当我右键单击菜单时,我想删除它。
通常用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()

1 个答案:

答案 0 :(得分:1)

据我所知,您的问题基本上有两个部分:

  1. 菜单栏项目可以在以后分配吗?

  2. 然后可以将引用的项目绑定到事件吗?


第一个答案是。虽然无法精确分配对象,但您可以 通过索引引用它,如下所示:

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>> bindingThat by itself is not useful to your quest,但您可以将event statecheckbutton的{​​{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的支持者,它使可访问变量和标志变得更加容易,而不必担心tkinterglobal命名空间。在这里,由于nonlocal是在delete_checkbutton命名空间中设置的,因此我使用了global关键字,并通过global对象对其进行了访问。但是,如果您要使用python布尔值(例如tk.BooleanVar()),那么除非您在两个函数中都指定flag = True,否则它的效果将不那么理想。但是,如果您采用OOP方法,则可以直接通过global flag毫无疑问地引用这些标志。


最后,以下是在代码中实施的全面更改以进行采样:

self.flag

所有,我认为这不是一个非常流畅的用户体验,并且有些令人困惑。仅仅永久删除菜单项最多是有问题的,再加上您尝试调用该删除方法时,您会感到更加人为。我建议您重新考虑您的UX流,以考虑如何简化它。