子菜单项不调用函数[有工作解决方案]

Lix*_*xas 4 python pygtk contextmenu menu

    #submenu
    clearMenu = gtk.Menu()

    item = gtk.MenuItem("submenu item")
    item.connect("activate", lambda w: self.callBackFunction())
    clearMenu.append(item)
    item.show()


    '''TOP level'''
    menu = gtk.Menu()

    item = gtk.ImageMenuItem("Item1")
    img = gtk.Image()
    img.set_from_file('image1.png')
    item.set_image(img)
    menu.append(item)
    item.set_submenu(clearMenu) #attach submenu
    item.show()

    item = gtk.ImageMenuItem("Item2")
    img = gtk.Image()
    img.set_from_file('image2.png')
    item.set_image(img)   
    item.connect("activate", lambda w: self.callBackFunction())
    menu.append(item)
    item.show()
Run Code Online (Sandbox Code Playgroud)

我的顶级项"Item2"调用定义的函数"callBackFunction".但为什么"子菜单项" ?我做错了什么?


编辑

这是我如何设法强制子菜单项启动所需的操作:

item.connect("button-press-event", self.callBackFunction, argument1, argument2)
Run Code Online (Sandbox Code Playgroud)

但我仍然不明白为什么事件"激活"不适用于子菜单项,而在顶级菜单项中工作

Tho*_*erl 5

虽然"button-press-event"有效但它有一些缺点:

  • 它不适用于仅键盘导航
  • 如果回调阻塞,则整个X Server被阻止(参见gPodder bug 1778)

对于我自己的应用程序(gPodder),我已经在提交a09b204a中解决了这个问题.

我们想要什么:

  1. "activate"信号做出反应(用于键盘导航以及单击父菜单项的情况)
  2. "button-press-event"信号做出反应(解决bug)
  3. 在下一个主循环迭代中运行回调(以避免阻塞X Server)
  4. 确保回调只被调用一次("activate"并且"button-press-event"在某些情况下都可以发生)

对于1.和2.我们可以简单地连接到两个信号.对于3.我们可以使用gobject.idle_add().对于4.我们可以使用a threading.Semaphore.

这导致以下代码:

import threading
import gobject

def submenu_item_connect_hack(menu_item, callback, *args_for_callback):
    only_once = threading.Semaphore(1)

    def handle_event(item, event=None):
        if only_once.acquire(False):
            gobject.idle_add(callback, *args_for_callback)

    menu_item.connect('button-press-event', handle_event)
    menu_item.connect('activate', handle_event)
Run Code Online (Sandbox Code Playgroud)

您现在可以在代码中使用它,如下所示:而不是调用以下代码之一:

item.connect("activate", lambda w: self.callBackFunction())
item.connect("button-press-event", self.callBackFunction, argument1, argument2)
Run Code Online (Sandbox Code Playgroud)

你这称之为:

submenu_item_connect_hack(item, self.callBackFunction, argument1, argument2)
Run Code Online (Sandbox Code Playgroud)

另外,在GNOME Bugzilla中提交了错误695488.