How to create a custom widget in GTK3 in C?

Do you know how to create a custom widget in GTK 3? I tried a subclass of GtkDrawingArea in C for hours. Gnome.org provides only a brief guide to the subclass of G_OBJECT. My problem is that G_Object / GTK cannot see my custom StrokerNodalContainer as a subclass of GtkWidget when casting using GTK_WIDGET , even my hard definition of struct contains the following line:

 GtkDrawingArea parent_instance; 

It says:

 invalid cast from 'StrokerNodalContainer' to 'GtkWidget' 

Here is the complete code if you suspect that something else might be wrong. This is minimal, so I see no reason why the external code is being violated.

Stroker-nodalcontainer.h

 #ifndef __STROKER_NODALCONTAINER_H__ #define __STROKER_NODALCONTAINER_H__ #ifndef NO_INCLUDE_WITHIN_HEADERS #include <gtk/gtk.h> #endif #define STROKER_TYPE_NODAL_CONTAINER (stroker_nodal_container_get_type ()) #define STROKER_NODAL_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STROKER_TYPE_NODAL_CONTAINER, StrokerNodalContainer)) #define STROKER_NODAL_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), STROKER_TYPE_NODAL_CONTAINER, StrokerNodalContainerClass)) #define STROKER_IS_NODAL_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STROKER_TYPE_NODAL_CONTAINER)) #define STROKER_IS_NODAL_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), STROKER_TYPE_NODAL_CONTAINER)) #define STROKER_NODAL_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), STROKER_TYPE_NODAL_CONTAINER, StrokerNodalContainerClass)) typedef struct _StrokerNodalContainer StrokerNodalContainer; typedef struct _StrokerNodalContainerClass StrokerNodalContainerClass; struct _StrokerNodalContainer { GtkDrawingArea parent_instance; }; struct _StrokerNodalContainerClass { GtkDrawingAreaClass parent_class; }; GType stroker_nodal_container_get_type(void); //StrokerNodalContainer* stroker_nodalcontainer_new(void); #endif /* __STROKER_NODALCONTAINER_H__ */ 

Stroker-nodalcontainer.c

 #include <gtk/gtk.h> #include "stroker-nodalcontainer.h" G_DEFINE_TYPE( StrokerNodalContainer, stroker_nodal_container, G_TYPE_OBJECT ) static void stroker_nodal_container_class_init( StrokerNodalContainerClass* klass ) {} static void stroker_nodal_container_init( StrokerNodalContainer* self ) { GdkRGBA c; GtkWidget *widget; gdk_rgba_parse(&c, "blue"); widget = GTK_WIDGET(self); gtk_widget_override_background_color( widget, GTK_STATE_FLAG_NORMAL, &c ); } 

main.c

 #include <stdlib.h> #include <stdio.h> #include <gtk/gtk.h> #include <cairo/cairo.h> #include "stroker-nodalcontainer.h" int main(int argc, char *argv[]) { GtkWidget *window; GtkWidget *nodalWidget; gtk_init( &argc, &argv ); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window), "Stroker"); g_signal_connect( window, "destroy", G_CALLBACK (gtk_main_quit), NULL ); gtk_container_set_border_width( GTK_CONTAINER(window), 10 ); gtk_widget_show (window); nodalWidget = g_object_new(STROKER_TYPE_NODAL_CONTAINER,NULL); gtk_container_add( GTK_CONTAINER(window), nodalWidget ); gtk_widget_show (nodalWidget); gtk_main(); return EXIT_SUCCESS; } 

Thanks for the help!

+5
source share
1 answer

Probably the error message is:

 G_DEFINE_TYPE( StrokerNodalContainer, stroker_nodal_container, G_TYPE_OBJECT ) 

If you look at the documentation for G_DEFINE_TYPE () , you will see that the third argument should be the parent type: you probably want GTK_TYPE_DRAWING_AREA here.

+4
source

Source: https://habr.com/ru/post/1202499/


All Articles