【发布时间】:2017-02-22 17:48:34
【问题描述】:
借助Keybinder 库,Python 3 和 Gtk 3.22.5 应用程序响应全局键绑定。目前它调用一个简单的回调:
def keybinder_callback(self, keystr, user_data):
print("Handling", keystr, user_data)
应用程序的其他地方是一个Gtk.Window,其中包含一个Gtk.MenuBar。 keybinder_callback 需要像用户点击鼠标一样激活菜单栏。
(这是一个非常基本的停靠式应用程序,而不是具有典型应用程序窗口的应用程序)
我已尝试向菜单项发送信号:
self.menubar.get_children()[0].emit("activate-item")
没有任何喜悦。我也试过假装按下按钮
from Xlib.ext.xtest import fake_input
fake_input(display,X.ButtonPress,1)
这也没有效果,但无论如何感觉都是错误的方法。我认为发送信号会更合适。
能否像用户点击鼠标一样以编程方式激活小部件?
(它不必是模拟的鼠标点击 - 它只需要以与鼠标点击相同的方式激活和聚焦小部件)
我写了一个example,其中有一个keybinder_callback,如下所示:
def keybinder_callback(self, keystr, user_data):
print("Handling", keystr, user_data)
print("Event time:", Keybinder.get_current_event_time())
activate_the_menu()
我需要向该函数添加一些命令,该命令将 activate_the_menu。
我尝试了很多方法,包括捕获真实事件(通过使用xev 进行监控)并模拟它们(ENTER_NOTIFY 和FOCUS_CHANGE),将它们注入Gdk.main_do_event。
我试过打电话给menu.popup、menu.popup_at_widget、menubar.select_item 和其他很多东西。一切都无济于事。
没有什么想法了,我什至把我的旧 Xlib 书掸掉了……
顺便说一句,虽然这不是一个合适的解决方案,但它可以在 shell 中工作:
$ xdotool mousemove 1605 10 click 1 mousemove restore
但不可靠来自keybinder_callback:
run("xdotool mousemove %d 10 click 1 mousemove restore" %
(self.get_position().root_x+5) , shell=True)
【问题讨论】:
-
看看
GtkMenu.popup_at_widget,但要小心,我在玩的时候差点把我的电脑冻住了。不太清楚发生了什么,但弹出菜单后我无法再关闭程序。 -
好吧,我尝试了
self.menu.popup_at_widget(self,Gdk.Gravity.STATIC,Gdk.Gravity.STATIC,None),但得到了Warning: g_object_set_data: assertion 'G_IS_OBJECT (object)' failed