问题描述
将任何 gtk.Widget 放入 gtk.Menu 中可以通过首先放入一个空的 gtk.MenuItem 来实现。它看起来并不可靠——但它基本上有效。使用 appindicator.Indicator ,它不起作用。该条目只是保持空白。例如,即使您将 child[border_size] 设置为 32。
唯一有效的小部件是 gtk.Label(当然还有 MenuItem、ImageMenuItem 等)。
现在我的菜单中有一个 gtk.Entry,所以肯定可以正确地执行此操作。我该怎么做?
这是一些示例代码来解释我的意思:
self.item = gtk.MenuItem()
self.item.add(gtk.Label("hello world!"))
self.menu.append(self.item)
上面的代码有效,但是以下代码无效:
self.item = gtk.MenuItem()
self.item.add(gtk.Entry())
self.menu.append(self.item)
其中self.menu是appindicator.Indicator,如果是gtk.Menu,至少会显示Entry。
这是一些工作代码:
import gtk
import appindicator
class AppIndicator (object):
def __init__(self):
self.ind = appindicator.Indicator("hello world client",
"distributor-logo", appindicator.CATEGORY_APPLICATION_STATUS)
self.ind.set_status (appindicator.STATUS_ACTIVE)
self.menu = gtk.Menu()
item = gtk.MenuItem()
item.add(gtk.Label("hello world"))
# item.add(gtk.Entry())
self.menu.append(item)
self.menu.show_all()
self.ind.set_menu(self.menu)
indicator = AppIndicator()
gtk.main()
最佳办法
应用程序指示器菜单支持基于 D-Bus 菜单,这些菜单的支持范围有限 – 它们仅支持基本菜单功能,不支持更奇特的功能,例如任意小部件。
他们支持此类事情的一个重要障碍是应用程序指示器菜单是由不同的进程(应用程序指示器进程)呈现的,因此您的程序无法直接在其上绘制任何内容。克服这个问题需要支持 D-Bus 菜单中的 X-Embed 之类的内容,或者允许所有 GTK 在 D-Bus 上工作。
次佳办法
Ubuntu 中的声音指示器有音量滑块,我想知道这是怎么可能的。查看代码后,似乎有 GtkMenus 可以同时通过 dbus 填充:\n https://developer.ubuntu.com/api/devel/ubuntu-12.04/c/dbusmenugtk/index.html
但我不知道如何使用它们。\n想编写一个声音指示器,我可以在其中控制音量 per-app,就像 pavucontrol 可以做到的那样。