How do I add a custom gtkmm widget to glade?
我正在使用 gtkmm 编写一个自定义小部件,但我无法让它在 Glade 中工作。 (小部件本身几乎没有功能;它确实可以工作,我想让它在 glade 中工作,然后再继续下一步。) Glade 找到了小部件,但是当我尝试将它放在窗口中时,glade 崩溃了。
根据我在各种搜索中发现的提示,我将这段代码添加到主源文件中:
1 2 3 4 5 6 7 | extern"C" { GType date_chooser_get_type(void) { return DateChooser::get_type(); } } |
我怀疑上面的代码不正确,但我找不到任何关于这个函数应该做什么的 gtkmm 或 glade 文档。
根据 glade 的目录文档,我创建了以下 XML:
1 2 3 4 5 6 7 8 9 | <?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> |
它位于我的小部件源目录的根目录中,名称为
1 | GLADE_CATALOG_SEARCH_PATH=. GLADE_MODULE_SEARCH_PATH=./.libs glade |
当窗口出现时,我的小部件出现在目录中指定的特殊"日期"组中,并带有默认图标。如果我放置一个窗口,然后选择要在窗口中放置的小部件,glade 会崩溃。我在控制台上看到以下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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 |
似乎这个(未回答的)问题的答案可能会提供线索,但我无法找到该问题的任何答案或有助于解决我的问题的线索。
我正在使用的版本:
- Ubuntu:12.04
- gtkmm:3.4.0-0ubuntu1
- 林间空地:3.12.0-0ubuntu1
(我愿意根据主干版本或 Centos 6 或 Fedora 16 测试解决方案。)
将自定义 gtkmm 小部件添加到 Glade 需要以下内容:
职能
最重要的是 Glade 是用 C 而不是 C 编写的,所以我们必须能够将 plan C 小部件package到 C 小部件中,并且我们必须将此package功能注册到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | #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); } |
您应该非常仔细地编写目录文件。名称必须正确(尤其是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?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 库初始化的一部分。
1 2 3 4 5 6 | extern"C" void custom_widgets_glade_init () { Gtk::Main::init_gtkmm_internals (); custom_widgets_register (); } |
初始化 gtkmm 内部是必须的,因为
如果您对该主题感兴趣,可以在此处找到我的博客文章,其中包含更多详细信息。