2012-05-31 74 views
8

我正在寫一個custom widget using gtkmm,我還沒有能夠讓它在空地上工作。 (小部件本身幾乎沒有功能,它確實有效,並且我希望在繼續下一步之前讓它在空地中工作。)Glade發現了這個小部件,但是當我嘗試將它放置在一個窗口中時,glade崩潰。如何將自定義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_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
  • 空地:3.12.0-0ubuntu1

(我會願意測試基於中繼版本或Centos 6或Fedora 16的解決方案。)

+0

您的自定義小部件是一個Gtk :: DrawingArea(或可以像那樣實現)? – higuaro

+0

我有同樣的問題。它似乎正在發生,因爲新類型沒有正確註冊。這又取決於在庫初始化函數中調用'Gtk :: Main :: init_gtkmm_internals()',這樣做可以防止glade正常啓動。儘管如此,還沒有弄清楚爲什麼。 – Tom

+0

@ h3nr1x:不可以。看看上面鏈接的代碼 - 這非常簡單。 – bstpierre

回答

5

以下是添加自定義gtkmm的小部件格萊德

  1. 至少一個純粹的自定義部件實現
  2. 一些格萊德 - 相關附加功能的自定義部件
  3. 它描述了自定義的小部件格萊德目錄文件
  4. 一個庫包含自定義小部件和一些格萊德相關 函數

最重要的事情是,格萊德是寫在Ç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> 

沒有什麼可以做的,但實現的功能,其註冊我們的widget作爲我們格萊德庫的初始化的一部分。

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

初始化gtkmm的內部是必須的,因爲custom_widgets_glade_init沼地,這是寫在ÇC++稱爲所以它僅初始化GTK +

如果您對該主題感興趣,您可以在我的博客文章here中查看更多詳情。

+0

感嘆。在經過了很長時間的打擊後,我意識到所給出的例子只適用於gtk-- 3.0,而不適用於2.4。 – Tom

+0

據我所知,它適用於_gtkmm_ 2.x.我用適當的命令完成了[我的博客文章](http://szilard.blogs.balabit.com/zh/2012/06/how-to-add-custom-gtkmm-widget-to-glade/)(代碼編譯,_Glade_相關的環境變量)和註釋。 –

相關問題