1

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

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

当我查看溢出菜单时,我应该看到“代理”作为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);
    }
}
4

1 回答 1

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;
}

您实际上可能不想在每次触发信号时都创建一个新代理,但这应该足以帮助任何阅读本文的人入门。

于 2012-07-09T19:07:55.097 回答