7

do you know how do you create a custom widget in GTK 3 ? I tried to subclass GtkDrawingArea in C for hours. Gnome.org only provides a succinct tutorial on how to subclass G_OBJECT. My issue is that G_Object/GTK fails to view my custom StrokerNodalContainer as a subclass of GtkWidget when casting with GTK_WIDGET, even tough my definition struct contains a line like this :

GtkDrawingArea parent_instance;

It says :

invalid cast from 'StrokerNodalContainer' to 'GtkWidget'

Here is the full code if you suspect something else might be wrong. It's minimal so I don't see any reason for external code to mess up.

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

Thank you for any help !

5
  • there is an example on the official wiki but it's using Vala, not C, wiki.gnome.org/Projects/Vala/CustomWidgetSamples Commented Sep 13, 2014 at 15:10
  • Yeah, but Vala or C++ or java or python are so easy : the class inheritance feature is within the core of the language, so they just use that. I'm failing to have my GObject inheritance recognised. Commented Sep 13, 2014 at 16:09
  • Vala compiles down to C89 + Glib + Gobject, I suggest the following: code something basic in Vala, compile Vala to C, inspect the generated C code . Commented Sep 13, 2014 at 16:13
  • 2
    I wrote a tutorial on this once: ptomato.name/advanced-gtk-techniques/html/custom-container.html Commented Sep 14, 2014 at 6:29
  • Maybe you could edit the title so it states your actual problem? Commented May 14, 2020 at 5:46

1 Answer 1

7

The error message is probably because of this:

G_DEFINE_TYPE( StrokerNodalContainer, stroker_nodal_container, G_TYPE_OBJECT )

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

Sign up to request clarification or add additional context in comments.

1 Comment

That was it. The tutorial was pretty quick and said "the parent GType".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.