如何向glade添加自定义gtkmm小部件?

时间:2012-05-31 01:40:21

标签: gtk widget glade gtkmm

我正在写一个custom widget using gtkmm,我无法让它在林间空地里工作。 (小部件本身几乎没有功能;它确实有效,我希望在进入下一步之前让它在林间空地工作。)Glade找到小部件,但是当我尝试将它放在窗口中时,林间空地崩溃。

根据我在各种搜索过程中发现的提示,我将这段代码添加到主源文件中:

extern "C"
{
    GType date_chooser_get_type(void)
    {
        return DateChooser::get_type();
    }
}

我怀疑上面的代码不对,但是我找不到任何关于这个函数应该做什么的gtkmm或glade文档。

基于catalog documentation for glade,我创建了以下XML:

<?xml version="1.0" encoding="UTF-8"?>
<glade-catalog name="gtk-date-chooser" library="libgtkdatechooser-0.1.so" language="c++">
  <glade-widget-classes>
    <glade-widget-class name="DateChooser" generic-name="date-chooser" title="Date Chooser" />
  </glade-widget-classes>
  <glade-widget-group name="date" title="Date">
    <glade-widget-class-ref name="DateChooser"/>
  </glade-widget-group>
</glade-catalog>

这是我的小部件源目录的根目录,名称为gtk-date-chooser.xml。我使用以下命令在该目录中运行glade:

GLADE_CATALOG_SEARCH_PATH=. GLADE_MODULE_SEARCH_PATH=./.libs glade

当窗口出现时,我的窗口小部件显示在目录中指定的特殊“日期”组中,并带有默认图标。如果我放置一个窗口,然后在窗口中选择要放置的小部件,则会发生崩溃。我在控制台上看到以下内容:

GladeUI-Message: 2 missing displayable value for GtkWidget::events
GladeUI-Message: No displayable values for property GtkTreeSelection::mode
GladeUI-Message: 1 missing displayable value for GtkCellRendererAccel::accel-mode
GladeUI-Message: 14 missing displayable value for GtkCellRendererAccel::accel-mods

(glade:23757): GladeUI-CRITICAL **: gwa_list_signals: assertion `real_type != 0' failed

(glade:23757): GLib-GObject-WARNING **: cannot retrieve class for invalid (unclassed) type `<invalid>'

(glade:23757): GLib-GObject-CRITICAL **: g_object_class_list_properties: assertion `G_IS_OBJECT_CLASS (class)' failed

(glade:23757): GLib-GObject-WARNING **: cannot retrieve class for invalid (unclassed) type `<invalid>'

(glade:23757): Gtk-CRITICAL **: gtk_container_class_list_child_properties: assertion `GTK_IS_CONTAINER_CLASS (cclass)' failed
GladeUI-Message: Glade needs artwork; a default icon will be used for the following classes:
    DateChooser needs an icon named 'widget-gtk-date-chooser-date-chooser'
**
GladeUI:ERROR:glade-signal-model.c:800:glade_signal_model_iter_n_children: code should not be reached

似乎this (unanswered) question的答案可能提供线索,但我无法找到任何可以帮助解决问题的答案或线索。

我正在使用的版本:

  • Ubuntu:12.04
  • gtkmm:3.4.0-0ubuntu1
  • glade:3.12.0-0ubuntu1

(我愿意根据主干版本或Centos 6或Fedora 16测试解决方案。)

1 个答案:

答案 0 :(得分:5)

以下内容是向 Glade 添加自定义 gtkmm 小部件所必需的:

  1. 至少一个纯自定义窗口小部件实现
  2. 一些 Glade 相关的自定义小部件的额外功能
  3. 描述Glade
  4. 自定义小部件的目录文件
  5. 一个库包含自定义小部件和一些与Glade相关的小部件 功能
  6. 最重要的是 Glade 是用 C 而不是 C ++ 编写的,所以我们必须能够包装一个将 C 小部件计划到 C ++ ,我们必须将此包装函数注册到与自定义小部件相关的GType。它看起来像下面这样:

    #include "custom_widget.h"
    
    GType CustomWidget::gtype = 0;
    
    CustomWidget::CustomWidget (GtkEntry *gobj) :
      Gtk::Entry (gobj)
    {
    }
    
    CustomWidget::CustomWidget () :
      Glib::ObjectBase ("customwidget")
    {
    }
    
    Glib::ObjectBase *
    CustomWidget::wrap_new (GObject *o)
    {
      if (gtk_widget_is_toplevel (GTK_WIDGET (o)))
        {
          return new CustomWidget (GTK_ENTRY (o));
        }
      else
        {
          return Gtk::manage(new CustomWidget (GTK_ENTRY (o)));
        }
    }
    
    void
    CustomWidget::register_type ()
    {
      if (gtype)
        return;
    
      CustomWidget dummy;
    
      GtkWidget *widget = GTK_WIDGET (dummy.gobj ());
    
      gtype = G_OBJECT_TYPE (widget);
    
      Glib::wrap_register (gtype, CustomWidget::wrap_new);
    }
    

    您应该非常仔细地编写目录文件。对于正确的工作,名称必须正确(尤其是glade-widget-class)。

    <?xml version="1.0" encoding="UTF-8" ?>
    <glade-catalog name="customwidgets" library="customwidgetsglade" depends="gtk+">
    
      <init-function>custom_widgets_glade_init</init-function>
    
      <glade-widget-classes>
        <glade-widget-class name="gtkmm__CustomObject_customwidget" generic-name="customwidget" icon-name="widget-gtk-entry" title="Custom Widget">
        </glade-widget-class>
      </glade-widget-classes>
    
      <glade-widget-group name="customwidgets" title="Custom Widgets" >
        <glade-widget-class-ref name="gtkmm__CustomObject_customwidget" />
      </glade-widget-group>
    
    </glade-catalog>
    

    没有任何事情可做,但实现了这个函数,它将我们的小部件注册为 Glade 库初始化的一部分。

    extern "C" void
    custom_widgets_glade_init ()
    {
      Gtk::Main::init_gtkmm_internals ();
      custom_widgets_register ();
    }
    

    初始化 gtkmm 内部是必须的,因为custom_widgets_glade_init是从 Glade调用的,是用 C 而不是< em> C ++ 所以它只初始化 GTK +

    如果您对该主题感兴趣,可以查看我的博文here,了解更多详情。