为什么我的工具项目的代理菜单项没有被使用?

时间:2012-07-06 22:13:28

标签: gtk glib vala gobject

我想在工具栏的溢出菜单中显示ToolItem的自定义菜单项。这似乎是set_proxy_menu_item方法的目的。但是,当我使用此方法设置代理菜单项时,它对溢出菜单没有影响。它仍然使用默认菜单项(ToolItem的名称作为标签)。

这是一个简单的项目(在Vala中),可以重现问题。它创建了一个包含带3个按钮的工具栏的小窗口。窗口应该足够小,除了其中一个按钮之外的所有按钮都在溢出菜单中。

当我查看溢出菜单时,我应该看到“proxy”作为edit_button的菜单项。相反,我看到“编辑”。

我做错了什么?

void main(string[] args) {
    Gtk.init(ref args);
    MainWindow main_window = new MainWindow();
    main_window.show_all();
    Gtk.main();
}

public class MainWindow : Gtk.Window {
    public MainWindow() {
        destroy.connect(Gtk.main_quit);
        title = "Main Window";

        Gtk.Box main_box = new Gtk.Box(Gtk.Orientation.VERTICAL, 6);
        add(main_box);

        Gtk.Toolbar toolbar = new Gtk.Toolbar();
        main_box.pack_start(toolbar, false, false);

        Gtk.ToolButton new_button = new Gtk.ToolButton.from_stock(Gtk.Stock.NEW);
        Gtk.ToolButton edit_button = new Gtk.ToolButton.from_stock(Gtk.Stock.EDIT);
        Gtk.ToolButton delete_button = new Gtk.ToolButton.from_stock(Gtk.Stock.DELETE);

        Gtk.MenuItem proxy = new Gtk.MenuItem.with_label("proxy");
        proxy.show_all();
        edit_button.set_proxy_menu_item("proxy_menuitem", proxy);

        toolbar.add(new_button);
        toolbar.add(edit_button);
        toolbar.add(delete_button);

        Gtk.Label content_label = new Gtk.Label("Placeholder");
        main_box.pack_start(content_label, false, false);
    }
}

1 个答案:

答案 0 :(得分:1)

事实证明set_proxy_menu_item是临时的,应该用于对create-menu-proxy信号的响应。我无法在网络上的任何地方找到此文档,但这里来自Gtk +源代码:

/**
 * GtkToolItem::create-menu-proxy:
 * @tool_item: the object the signal was emitted on
 *
 * This signal is emitted when the toolbar needs information from @tool_item
 * about whether the item should appear in the toolbar overflow menu. In
 * response the tool item should either
 * <itemizedlist>
 * <listitem>call gtk_tool_item_set_proxy_menu_item() with a %NULL
 * pointer and return %TRUE to indicate that the item should not appear
 * in the overflow menu
 * </listitem>
 * <listitem> call gtk_tool_item_set_proxy_menu_item() with a new menu
 * item and return %TRUE, or 
 * </listitem>
 * <listitem> return %FALSE to indicate that the signal was not
 * handled by the item. This means that
 * the item will not appear in the overflow menu unless a later handler
 * installs a menu item.
 * </listitem>
 * </itemizedlist>
 *
 * The toolbar may cache the result of this signal. When the tool item changes
 * how it will respond to this signal it must call gtk_tool_item_rebuild_menu()
 * to invalidate the cache and ensure that the toolbar rebuilds its overflow
 * menu.
 *
 * Return value: %TRUE if the signal was handled, %FALSE if not
 **/

所以解决这个问题的正确方法就是:

edit_button.create_menu_proxy.connect(on_create_menu_proxy);

...

private bool on_create_menu_proxy(Gtk.ToolItem tool_item) {
    Gtk.MenuItem proxy = new Gtk.MenuItem.with_label("proxy");
    tool_item.set_proxy_menu_item("proxy_menuitem", proxy);
    return true;
}

每次触发信号时,您可能实际上并不想创建新的代理,但这应该足以帮助任何阅读此内容的人开始使用。