gpt4 book ai didi

Python tkinter : Delete Menu checkbutton

转载 作者:行者123 更新时间:2023-12-01 08:42:54 25 4
gpt4 key购买 nike

我想在右键单击菜单复选按钮时删除它。
它通常用 bind("Mouse3", deletefunction) 完成,但我需要一个复选按钮的实际实例来绑定(bind)它,并且我知道将复选按钮添加到菜单的唯一方法是 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. 之后可以指定菜单栏项进行操作吗?

  2. 可以将引用的项目绑定(bind)到事件吗?

<小时/>

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

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 ,这会很方便,除非您多次使用相同的标签...

<小时/>

第二个答案,据我所知,对于鼠标点击等典型事件似乎没有任何有效的绑定(bind)。然而,经过一番搜索后,我确实遇到了 rather hidden <<MenuSelect>> binding至少会触发一个事件。 That by itself is not useful to your quest ,但您可以组合 event statecheckbuttoncommand参数以及一个 bool 标志来触发点击事件:

# 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 是您可能会考虑的另一种模式状态。

另一个旁注:当谈到 tkinter 时,我是 OOP 的支持者。 ,它使可访问的变量和标志变得更加容易,而无需担心 globalnonlocal命名空间。从这里开始delete_checkbutton设置在 global我避免使用 global 的命名空间关键字并通过 tk.BooleanVar() 访问它目的。但是,如果您要使用 python bool 值(例如 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()

综上所述,我认为这不是一个非常流畅的用户体验,而且有些令人困惑。仅永久删除菜单项充其量是值得怀疑的,与您尝试调用删除的方法相结合感觉更加做作。我建议重新审视您的用户体验流程,考虑如何简化此流程。

关于Python tkinter : Delete Menu checkbutton,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53436119/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com