使用 PyGObject 获取 GDBusMenuModel 的菜单项



因为我安装了unity-gtk模块,所以所有gtk应用程序都通过dbus SessionBus导出它们的菜单。我的目标是提取所有可用菜单项的列表。我已经在pydbus的帮助下实现了这个,但是由于某种原因,这个解决方案非常不稳定,有些应用程序只是崩溃。unity-gtk-module使用Gio的g_dbus_connection_export_menu_model()通过dbus导出其GMenuModel建模菜单,所以我认为尝试使用Gio来处理导出的菜单是有意义的。Gio 使用 GDBusMenuModel 类从总线中检索菜单。Python 使用 PyGObject 来包装 Gio:

from gi.repository import  Gio
connection = Gio.bus_get_sync(Gio.BusType.SESSION, None)
menuModel = Gio.DBusMenuModel.get(connection, [bus-name e.g. ":1.5"], [object-path e.g. "/com/canonical/unity/gtk/window/0"])

现在menuModel应该从我的应用程序中包装GMenuModel。在这一点上,老实说,我对GMenuModel的工作原理有点困惑(描述并没有真正的帮助),但似乎我必须使用GMenuAttributeIter对象来迭代条目。但是当我尝试这个时:

iter = Gio.MenuModel.iterate_item_attributes(menuModel, 0) #0 is the index of the root node

这种情况发生:

GLib-GIO-CRITICAL **: g_dbus_menu_model_get_item_attributes: assertion 'proxy->items' failed
GLib-GIO-CRITICAL **: GMenuModel implementation 'GDBusMenuModel' doesn't override iterate_item_attributes() and fails to return sane calues from get_item_attributes()

这可能是因为GDBusMenuModel继承了GMenuModel,它提供了这些方法,但是它是抽象的,所以GDBusMenuModel应该覆盖它们,但它没有(见上面的链接,它只提供g_dbus_menu_model_get())。如果是这种情况,我应该如何实际使用此类作为代理?如果不是,我做错了什么?

几年后我第一次登录SO,并记得我实际上已经找到了这个问题的解决方案(我认为)。老实说,我不记得这些词的一半是什么意思,但当时我写了一个脚本来完成标题中提出的任务,据我所知,最后,它成功了:https://gist.github.com/encomiastical/caa0ee955300bc2a40ef55d123b06212

最新更新