Насколько я понимаю, ваш вопрос состоит из двух частей:
Можно ли назначить пункт меню для манипуляции после?
Может ли указанный элемент быть привязан к событию?
Первый ответ , вроде как.Хотя вы не можете точно назначить объект, вы можете ссылаться на него по индексу следующим образом:
view_menu.delete(0)
Поскольку вы сначала добавили checkbutton
, он будет иметь индекс0. Вы можете либо отслеживать индексы, либо ссылаться на элемент по его label
. См. Связанный ответ от Брайана Оукли .Например:
view_menu.delete(view_menu.index("Right click on me to delete"))
Метод .index()
обнаружит index
по элементу меню label
, что может быть удобно, если у вас один и тот же ярлык более одного раза ...
Второй ответ , насколько я знаю, кажется, что нет никакого эффективного связывания для типичных событий, таких как щелчки мышью.Однако после некоторого поиска я наткнулся на довольно скрытую <<MenuSelect>>
привязку , которая по крайней мере вызывает событие. Это само по себе бесполезно для вашего квеста , но вы можете объединить состояние события с аргументом 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 - другое состояние мода, которое вы могли бырассмотрим.
Еще одно замечание: я сторонник ООП, когда дело доходит до tkinter
, он делает доступные переменные и флаги намного проще, не беспокоясь о пространствах имен global
и nonlocal
.Здесь, поскольку delete_checkbutton
установлено в пространстве имен global
, я избегал использования ключевого слова global
и обращался к нему через объект tk.BooleanVar()
.Однако, если бы вы использовали булево значение Python (например, flag = True
), то оно не будет таким эффективным, если вы не укажете global flag
в обеих функциях.Однако, если вы выбрали подход ООП, вы можете ссылаться на флаги напрямую через self.flag
без двусмысленности.
Наконец , вот комплексные изменения, реализованные в вашем коде для выборки:1072 *
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-поток, чтобы подумать, как его упростить.