python - Python tkinter:删除菜单检查按钮
问题描述
当我右键单击它时,我想删除一个菜单检查按钮。
它通常用 来完成bind("Mouse3", deletefunction)
,但我需要一个检查按钮的实际实例来绑定它,并且将检查按钮添加到我知道的菜单的唯一方法是一种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()
解决方案
据我了解,您的问题基本上有两个部分:
之后可以分配菜单栏项以进行操作吗?
然后可以将引用的项目绑定到事件吗?
第一个答案是,有点。虽然您无法准确分配对象,但您可以通过索引引用它,如下所示:
view_menu.delete(0)
由于您添加了checkbutton
第一个,它的索引为 0。您可以跟踪索引,也可以通过它的label
. 请参阅 Bryan Oakley 的相关回答。例如:
view_menu.delete(view_menu.index("Right click on me to delete"))
该.index()
方法将index
通过菜单条目找到label
,这很方便,除非您多次使用相同的标签...
第二个答案,据我所知,对于鼠标点击等典型事件似乎没有任何有效的绑定。然而,经过一番搜索,我确实遇到了一个相当隐藏的<<MenuSelect>>
绑定,它至少会触发一个事件。 这本身对您的 quest 没有用,但您可以将事件状态与checkbutton
的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)
注意:您实际上必须按住右键单击然后左键单击以将checkbutton
其删除。显然,缺点是您现在已经触发了开/关值,您可能需要对它们进行一些额外的处理。
如果右键 + 左键单击太尴尬,Ctrl/Shift 是您可能会考虑的另一种模式状态。
另一个注意事项:当涉及到 时,我是 OOP 的支持者tkinter
,它使可访问的变量和标志变得更加容易,而无需担心global
和nonlocal
命名空间。这里因为delete_checkbutton
是在global
命名空间中设置的,我避免使用global
关键字并通过tk.BooleanVar()
对象访问它。但是,如果您要使用 python 布尔值(例如),那么除非您在两个函数中都指定,flag = True
否则它不会那么有效。global flag
但是,如果您采用 OOP 方法,则可以直接引用标志,self.flag
而不会产生歧义。
最后,以下是在您的采样代码中实施的全面更改:
import tkinter as tk
def event_state(e):
if bool(e.state & 0x0400):
# you might opt to use 0x0004 or 0x0001 instead
# i.e. Ctrl+click or Shift+Click
delete_checkbutton.set(True)
else:
delete_checkbutton.set(False)
def self_delete():
if delete_checkbutton.get():
view_menu.delete(view_menu.index("Right click on me to delete"))
root = tk.Tk()
menubar = tk.Menu(root)
delete_checkbutton = tk.BooleanVar()
view_menu = tk.Menu(menubar, tearoff=0)
view_menu.add_command(label='dude', command=lambda: print('dude'))
view_menu.add_checkbutton(label="Right click on me to delete", onvalue=lambda:print('hey'), offvalue=False, command=self_delete)
menubar.add_cascade(label='View', menu=view_menu)
root.config(menu=menubar)
view_menu.bind('<<MenuSelect>>', event_state)
root.mainloop()
综上所述,我认为这不是一个非常流畅的用户体验,而且有点令人困惑。仅永久删除菜单项充其量是有问题的,再加上您尝试调用删除的方法,感觉更加做作。我建议重新审视您的 UX 流程以考虑如何简化此流程。
推荐阅读
- processing - 我如何制作一个计数器来记录有多少人走过 Kinect 并在它检测处理中的新动作时让骨架改变颜色
- javascript - SAPUI5中的iframe:第一次加载URL更改为父页面后
- javascript - 如何使网页显示特定的数据库项?
- r - 发送“未分类”变量作为函数参数?
- html - 如何在所有生成的 html 文件中自动添加 css 导入?
- c# - 如何关闭客户端连接并返回 NETMQ 中的调用?
- javascript - “无法读取 null 的属性‘innerHTML’”错误
- java - 从 Angular 项目到 jhipster 的 jwt 连接
- azure-api-management - 如何在发布者/开发者门户上显示报告
- ios - 为什么 SwiftUI 上下文菜单在预览中显示所有行视图?