gtkmm和Gtk :: Builder:调用get_widget后对象的生命周期

时间:2014-04-26 19:48:01

标签: c++ gtk gtkmm

我认为我必须在这里“做错事”。我有一个使用gtkmm的程序。该程序的主窗口是Gtk::Window的子类,我在Glade中提取了应用程序的基础。

这是主窗口构造函数的编辑版本:

template<class T>
static T*
get_widget (Glib::RefPtr<Gtk::Builder> builder, const Glib::ustring& name)
{
    T* widget;
    builder->get_widget (name, widget);
    if (! widget) no_such_widget (name);

    return widget;
}

app_window::app_window ()
{
    Glib::RefPtr<Gtk::Builder> builder;

    try {
        builder = Gtk::Builder::create_from_file (installed_ui_name);
    }
    catch (const Glib::FileError& err) {
        g_error ("Couldn't open UI definition file at %s",
                 installed_ui_name);
        throw;
    }

    // main_box is a std::unique_ptr<Gtk::Widget>, a field of app_window.
    //
    // This works fine: the Gtk::Box gets added as the main child of this
    // app_window and survives until the app_window is destroyed.

    main_box.reset (get_widget <Gtk::Box> (builder, "main-box"));
    add (* main_box);

    auto accel_group = get_accel_group ();

    // This doesn't work so well
    //
    // menu_quit is a Gtk::MenuItem*. The object seems to be actually
    // constructed for the call to builder->get_widget, because its existence
    // stops the menu item from being finalized at the end of the application.

    auto menu_quit (get_widget<Gtk::MenuItem> (builder, "menu-quit"));

    menu_quit->add_accelerator ("activate", accel_group,
                                GDK_KEY_q, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE);

    using std::bind;
    menu_quit->signal_activate ().connect (bind (& app_window::on_close, this));

    show ();
}

设置窗口时,我想为菜单项等注册各种信号处理程序。(示例中的menu_quit小部件只是其中之一)。为此,我想我需要使用builder->get_widget()来获取要讨论的对象。

问题是我现在有一个({1}}的子类的实例,我不知道如何处理它。如果我在指针上调用delete,则小部件不会出现在应用程序中,但不会发生其他问题。这有点令人困惑:我希望无效或分段错误(取决于是否有其他人认为它拥有该对象)。

另一方面,如果我泄漏了指针,假设该对象将被添加了main_box的容器所拥有,则会出现内存泄漏。特别是,Gtk::Widget的基础menu_quit未完成,因为引用计数太高。 (我可以用GDB轻松检查)

“解决方案”是将gtk_image_menu_item作为builder->get_widget中的字段存储到每个对象的指针,然后在析构函数中将其删除(使用app_window自动删除或std::auto_ptr)。但那太可怕了:我不想为每一个菜单项写出一个字段!避免这种废话是首先使用std::unique_ptr的重点!

假设这不是一个错误(gtkmm 3.12.0,如果这是相关的),我认为我只是做错了。应用程序应该如何执行此操作?

0 个答案:

没有答案