【问题标题】:Why isn't my toolitem's proxy menu item being used?为什么我的工具项的代理菜单项没有被使用?
【发布时间】:2012-07-07 09:25:16
【问题描述】:

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

【问题讨论】:

    标签: gtk glib vala gobject


    【解决方案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;
    }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-09
      • 2019-03-21
      • 2019-12-03
      • 1970-01-01
      • 1970-01-01
      • 2019-05-20
      • 1970-01-01
      相关资源
      最近更新 更多