2012-05-31 14 views
8

Sto scrivendo uno custom widget using gtkmm e non sono stato in grado di farlo funzionare in glade. (Il widget stesso funziona a malapena, funziona e voglio farlo funzionare in glade prima di passare al prossimo passaggio.) Glade trova il widget, ma quando provo a metterlo in una finestra, glade si blocca.Come posso aggiungere un widget gtkmm personalizzato a glade?

Sulla base di suggerimenti che ho trovato durante le varie ricerche, ho aggiunto questo pezzo di codice al file principale fonte:

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

Ho il sospetto che il codice di cui sopra non è giusto, ma non ci riesco trova qualsiasi documentazione gtkmm o glade su cosa questa funzione dovrebbe fare.

Sulla base del catalog documentation for glade, ho creato il seguente codice 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> 

Questo è nella radice della directory di origine di mio Widget con il nome gtk-date-chooser.xml. Corro radura in quella directory usando:

GLADE_CATALOG_SEARCH_PATH=. GLADE_MODULE_SEARCH_PATH=./.libs glade 

Quando la finestra viene in su, il mio widget viene visualizzato in una speciale "Data" gruppo come specificato nel catalogo, con l'icona di default. Se metto una finestra e poi seleziono il widget per il posizionamento nella finestra, glade si blocca. Vedo il seguente sulla console:

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 

Sembra che la risposta a this (unanswered) question potrebbe fornire un indizio, ma non sono stato in grado di trovare una risposta per questa domanda o indizi che vi aiuterà con il mio problema.

versioni che sto usando:

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

(Sarei disposto a testare soluzioni basate su versioni trunk, o su Centos 6 o Fedora 16.)

+0

Il widget personalizzato è un Gtk :: DrawingArea (o potrebbe essere implementato in questo modo)? – higuaro

+0

Ho lo stesso problema. Sembra che stia accadendo perché il nuovo tipo non viene registrato correttamente. Questo a sua volta dipende dal chiamare 'Gtk :: Main :: init_gtkmm_internals()' in una funzione di inizializzazione della libreria, e così facendo impedisce a glade di avviarsi correttamente. Non ho ancora capito perché, però. – Tom

+0

@ h3nr1x: No. Dai un'occhiata al codice collegato sopra: è molto semplice. – bstpierre

risposta

5

Le seguenti operazioni sono necessarie per aggiungere un numero personalizzato gtkmm widget per Glade:

  1. almeno un'implementazione widget di pura personalizzato
  2. alcuni Glade -related funzioni aggiuntive ai widget personalizzati
  3. un file di catalogo che descrive i widget personalizzati per Glade
  4. una libreria contiene i widget personalizzati e alcune funzioni relative a Glade

La cosa più importante è il fatto che Glade è scritto in C non in C++, quindi dobbiamo essere in grado di avvolgere un piano di widget di C ad un C++ uno e dobbiamo registrare questa funzione di avvolgimento su GType correlata al widget personalizzato.Sembra qualcosa di simile ai seguenti:

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

È consigliabile scrivere il file di catalogo con molta attenzione. I nomi devono essere corretti (in particolare glade-widget-class) per il lavoro corretto.

<?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> 

Non c'è niente da fare, ma implementare la funzione, che registra il nostro widget come parte dell'inizializzazione del nostro Glade biblioteca .

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

inizializzazione gtkmm interni è un must, perché custom_widgets_glade_init viene richiamato da Glade, che è scritto in C non in C++ quindi inizializza solo il GTK +.

Se sei interessato all'argomento puoi trovare il mio post sul blog here con maggiori dettagli.

+0

Sigh.Dopo un * lungo * tempo a battere la testa contro questo, mi sono reso conto che l'esempio dato funziona solo con gtk-- 3.0, non con 2.4. – Tom

+0

Per quanto ne so funziona con _gtkmm_ 2.x. Ho completato [il mio post sul blog] (http://szilard.blogs.balabit.com/en/2012/06/how-to-add-custom-gtkmm-widget-to-glade/) con i comandi appropriati (compilazione del codice , _Glade_ variabili d'ambiente correlate) e note. –

Problemi correlati