Problem mit gdk_window_set_cursor() in GTK+ 3

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
3VAD_YNCAL
Beiträge: 51
Registriert: So Dez 04, 2011 3:14 am

Problem mit gdk_window_set_cursor() in GTK+ 3

Beitrag von 3VAD_YNCAL » So Aug 05, 2012 2:09 pm

Hallo zusammen,

ich arbeite zur Zeit das Buch von Andrew Krause "Foundations of GTK+ Development" durch. Mir ist auch vollkommen bewusst, dass sich das Buch an GTK+ 2 anlehnt. Allerdings nutze ich GTK+ 3, weil ich möglichst auf dem neuesten Stand der Dinge bleiben möchte. Bisher war ich auch glücklicherweise in der Lage, Beispielcodes des Buches so umzuschreiben, dass sie sich auch fehlerfrei unter GTK+ 3 kompilieren ließen.
Doch nun bräuchte ich Hilfe oder vielleicht einfach nur einen Tipp. :)

Hier zunächst das Listing:

Code: Alles auswählen

/* eventboxes.c */

#include <gtk/gtk.h>

/* compile: gcc -Wall -g eventboxes.c -o eventboxes `pkg-config --libs --cflags gtk+-3.0` */

static void destroy( GtkWidget *, gpointer );
static gboolean button_pressed( GtkWidget *, GdkEventButton *, GtkLabel * );

int main( int argc, char *argv[] )
{
    GtkWidget *window, *eventbox, *label;

    gtk_init( &argc, &argv );

    window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
    gtk_window_set_title( GTK_WINDOW( window ), "Event Box" );
    gtk_container_set_border_width( GTK_CONTAINER( window ), 10 );
    gtk_widget_set_size_request( window, 200, 50 );

    g_signal_connect( G_OBJECT( window ), "destroy",
		                G_CALLBACK( destroy ), NULL );

    eventbox = gtk_event_box_new();
    label    = gtk_label_new( "Double-Click Me!" );

    /* Set the order in which widgets will receive notification of events */
    gtk_event_box_set_above_child( GTK_EVENT_BOX( eventbox ), FALSE );

    g_signal_connect( G_OBJECT( eventbox ), "button_press_event",
		                G_CALLBACK( button_pressed ), ( gpointer ) label );

    gtk_container_add( GTK_CONTAINER( eventbox ), label );
    gtk_container_add( GTK_CONTAINER( window ), eventbox );

    /* Allow the event box to catch button presses, realize the widget, and set the *
     * cursor that will be displayed when the mouse is over the event box	    */
    gtk_widget_set_events( eventbox, GDK_BUTTON_PRESS_MASK );
    gtk_widget_realize( eventbox );
    gdk_window_set_cursor( eventbox->window, gdk_cursor_new( GDK_HAND1 ) );
    gtk_widget_show_all( window );

    gtk_main();

    return 0;
}

/* This is called every time a button-press event occurs on the GtkEventBox */
static gboolean button_pressed( GtkWidget *eventbox,
				                GdkEventButton *event,
				                GtkLabel *label )
{
    if( event->type == GDK_2BUTTON_PRESS )
    {
	const gchar *text = gtk_label_get_text( label );

	if( text[0] == 'D' )
	    gtk_label_set_text( label, "I Was Double-Clicked!" );

	else
	    gtk_label_set_text( label, "Double-Click Me Again!" );
    }

    return FALSE;
}

static void destroy( GtkWidget *window, gpointer data )
{
    gtk_main_quit();
}
Kurz zum Programm: Es wird ein Fenster erstellt mit einem Button. Der Button hat ein Label: "Double-Click Me!"
Wenn man jetzt immer wieder mit Double-Clicks auf das Button klickt, ändert sich das Label im Wechsel von "I Was Double-Clicked" zu "Double-Click Me Again!". Desweiteren ändert sich das Mauszeigersymbol sobald sich der Mauzeiger über den zu drückenden Button befindet.

Nun zum eigentlichen Problem bei der Kompilierung mit GTK+ 3:
Der Compiler meckert bei folgender Zeile im Quellcode:

Code: Alles auswählen

gdk_window_set_cursor( eventbox->window, gdk_cursor_new( GDK_HAND1 ) );
mit dieser Meldung:

Code: Alles auswählen

eventboxes.c: In Funktion »main«:
eventboxes.c:40:36: Fehler: »GtkWidget« hat kein Element namens »window«
Wie müsste ich das umschreiben, damit das auch unter GTK+ 3 fehlerfrei kompiliert werden kann?
Würde mich sehr über eure Hilfe freuen. ;)

Gruß Dave

PS: Das o.g. Listing ließ sich unter GTK+ 2 problemlos kompilieren.

hofian
Beiträge: 62
Registriert: Do Sep 24, 2009 6:59 pm

Re: Problem mit gdk_window_set_cursor() in GTK+ 3

Beitrag von hofian » So Aug 05, 2012 3:01 pm

Hallo!

Nun, gerade im GDK-Bereich wurde in Richtung GTK3 eine ganze Menge "altes Zeug" entfernt. Um an das GdkWindow zu gelangen, solltest du die Funktion gtk_widget_get_parent_window benutzen.

Code: Alles auswählen

gdk_window_set_cursor( gtk_widget_get_parent_window( eventbox ), gdk_cursor_new( GDK_HAND1 ) );
Löst dein Problem (hoffentlich).

Gruß Max

3VAD_YNCAL
Beiträge: 51
Registriert: So Dez 04, 2011 3:14 am

Re: Problem mit gdk_window_set_cursor() in GTK+ 3

Beitrag von 3VAD_YNCAL » So Aug 05, 2012 3:29 pm

Hallo Max,

Wow - ja man, dass konnte mein Problem beheben. Vielen vielen herzlichen Dank. Du hast mir schon zum zweiten Mal geholfen. Echt super nett von dir. :)

Grüße
Dave

hofian
Beiträge: 62
Registriert: Do Sep 24, 2009 6:59 pm

Re: Problem mit gdk_window_set_cursor() in GTK+ 3

Beitrag von hofian » So Aug 05, 2012 6:53 pm

Kein Problem,
man kennt eben die Stolpersteine besonders gut, über die man selber schon gefallen ist. ;)
Und gerade im Bereich GTK/GDK gibt es davon eine ganze Menge, gerade durch die ständige Weiterentwicklung.

Ich kann dir nur empfehlen, eine Offline-Referenz speziell für GTK mit eingebauter Suche wie Devhelp immer nebenbei offen zu haben. Und immer versuchen, Funktionen, die als deprecated markiert sind, zu meiden.

Sonst noch viel Glück und Erfolg in der GTK+-Welt!

3VAD_YNCAL
Beiträge: 51
Registriert: So Dez 04, 2011 3:14 am

Re: Problem mit gdk_window_set_cursor() in GTK+ 3

Beitrag von 3VAD_YNCAL » Mo Aug 06, 2012 12:17 pm

Dankeschön für die Tipps. Habe jetzt auch die GTK+3 Dokumentation nachinstalliert, nachdem ich deinen Rat bzgl. der Offline-Referenz gelesen habe. ;) Echt klasse von dir. :)

Antworten