2017-07-07 4 views
1

Ich arbeite gerade an einem Projekt, und ich versuche, 2 Callbacks miteinander kommunizieren zu lassen, indem Sie ihnen die gleiche Variable übergeben (die Callbacks teilen sich die gleiche Variable). Da die Callbacks keinen Wert zurückgeben können, habe ich einen Zeiger auf den Wert übergeben, der in der Hauptschleife (Hauptfunktion) zugewiesen ist. Allerdings funktioniert es überhaupt nicht!Wie zwischen Callbacks in gtk + c kommunizieren

Dies ist mein Code:

#include <gtk/gtk.h> 

static void inc_val (GtkWidget *widget, gpointer data) 
{ 
    int* value = data; 
    *value++; 
    printf("value is: %d\n", *value); 
} 

static void inc_val_ten (GtkWidget *widget, gpointer data) 
{ 
    int* value = data; 
    *value+=10; 
    printf("value is: %d\n", *value); 
} 

static void activate (GtkApplication *app, gpointer user_data) 
{ 
    GtkWidget *window; 
    GtkWidget *grid; 
    GtkWidget *button; 
    int value = 0; 

    window = gtk_application_window_new (app); 
    gtk_window_set_title (GTK_WINDOW (window), "Window"); 
    gtk_container_set_border_width (GTK_CONTAINER (window), 10); 

    grid = gtk_grid_new(); 
    gtk_container_add (GTK_CONTAINER (window), grid); 

    button = gtk_button_new_with_label ("Add 1 to value"); 
    g_signal_connect (button, "clicked", G_CALLBACK (inc_val), &value); 
    gtk_grid_attach (GTK_GRID (grid), button, 0, 0, 1, 1); 

    button = gtk_button_new_with_label ("Add 10 to value"); 
    g_signal_connect (button, "clicked", G_CALLBACK (inc_val_ten), &value); 
    gtk_grid_attach (GTK_GRID (grid), button, 1, 0, 1, 1); 

    button = gtk_button_new_with_label ("Quit"); 
    g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window); 
    gtk_grid_attach (GTK_GRID (grid), button, 0, 1, 2, 1); 

    gtk_widget_show_all (window); 
} 

int main (int argc, char **argv) 
{ 
    GtkApplication *app; 
    int status; 

    app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE); 
    g_signal_connect (app, "activate", G_CALLBACK (activate), NULL); 
    status = g_application_run (G_APPLICATION (app), argc, argv); 
    g_object_unref (app); 

    return status; 
} 

Das Programm verfügt über 3 Tasten im Fenster:

  1. 1 bis Wert
  2. Zugabe von 10 Hinzufügen
  3. Beenden des Programms zu schätzen

Wert ist ein inte Ger auf der Hauptschleife. Wenn eine der Tasten (erste oder zweite) gedrückt wird, wird der Wert größer (um 1 oder um 10) und das Programm druckt den neuen Wert.

Ich habe das Programm und klickte die Tasten laufen und das ist, was ich habe:

value is: 46525384 
value is: 46525384 
value is: 46157330 
value is: -830528646 
value is: 56 
value is: 10 

statt:

value is: 1 
value is: 2 
value is: 12 
value is: 22 
value is: 23 
value is: 33 

jemand weiß, warum geschehen ist das?

Vielen Dank für Ihre Hilfe!

Bearbeiten: Ich habe das gleiche Ding versucht, nur anstatt Zahlen zu einem Wert hinzuzufügen, habe ich versucht, Knopf zum Gitter hinzuzufügen. Da die Lösung aus der Antwort (unter der Frage) im vorherigen Code gearbeitet hat, habe ich das Grid global gemacht.

So, hier ist der neue Code:

#include <gtk/gtk.h> 
#include <stdlib.h> 
#include <stdio.h> 

GtkWidget *grid; 

static void add_button (GtkWidget *widget, gpointer data) 
{ 
    static int value = 0; 
    GtkWidget* grid = data; 
    value++; 
    printf("attach to line %d\n", value); 
    gtk_grid_attach(GTK_GRID(grid), gtk_button_new_from_stock(GTK_STOCK_NEW), 0, value, 1, 1); 
} 

static void activate (GtkApplication *app, gpointer user_data) 
{ 
    GtkWidget *window; 
    GtkWidget *button; 

    window = gtk_application_window_new (app); 
    gtk_window_set_title (GTK_WINDOW (window), "Window"); 
    gtk_container_set_border_width (GTK_CONTAINER (window), 10); 

    grid = gtk_grid_new(); 
    gtk_container_add (GTK_CONTAINER (window), grid); 

    button = gtk_button_new_with_label ("Add Button"); 
    g_signal_connect (button, "clicked", G_CALLBACK (add_button), grid); 
    gtk_grid_attach (GTK_GRID (grid), button, 0, 0, 1, 1); 

    gtk_widget_show_all (window); 
} 

int main (int argc, char **argv) 
{ 
    GtkApplication *app; 
    int status; 

    app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE); 
    g_signal_connect (app, "activate", G_CALLBACK (activate), NULL); 
    status = g_application_run (G_APPLICATION (app), argc, argv); 
    g_object_unref (app); 

    return status; 
} 

jedoch nicht aus irgendeinem Grund funktioniert hat. Hilfe wird geschätzt!

Antwort

1

Antwort auf die EDIT:

Sie müssen die Widgets zeigen, um sie zu verwirklichen. Einfachste Weg ist gtk_widget_show_all auf den übergeordneten Container zu nennen:

static void add_button (GtkWidget *widget, gpointer data) 
{ 
    static int value = 0; 
    GtkWidget* grid = data; 
    value++; 
    printf("attach to line %d\n", value); 
    gtk_grid_attach(GTK_GRID(grid), 
    gtk_button_new_from_stock(GTK_STOCK_NEW), 0, value, 1, 1); 
    gtk_widget_show_all(grid); 
} 

Eine weitere Möglichkeit, einen Verweis auf die Taste zu halten wäre und rufen gtk_widget_show auf diese Instanz. Beispiel:

static void add_button (GtkWidget *widget, gpointer data) 
{ 
    static int value = 0; 
    GtkWidget* grid = data; 
    GtkWidget* button = gtk_button_new_from_stock(GTK_STOCK_NEW); 

    value++; 
    printf("attach to line %d\n", value); 

    gtk_grid_attach(GTK_GRID(grid), button, 0, value, 1, 1); 
    gtk_widget_show (button); 
} 
+0

Danke für Ihre Hilfe! Kannst du mir damit helfen? https://stackoverflow.com/questions/44997120/printing-value-of-entry-box-in-a-dialog-in-gtk-c –

1

Die value ist lokal zu activate. Wenn activate abgeschlossen ist, sind seine lokalen Variablen verschwunden; Der Zeiger, den Sie an die Handler übergeben, ist jetzt bedeutungslos.

Die Lösung ist value eine ganze Lebensdauer der Anwendung zu überleben. Ein einfacher (aber möglicherweise nicht sauberster) Weg ist es, es global zu machen.

+0

Ich habe das gleiche mit dem Hinzufügen von Schaltfläche zu einem Raster versucht. Aber es hat auch nicht funktioniert.Ich habe die Frage mit weiteren Details bearbeitet. By the way, anstatt einer globalen Variable, funktioniert es mit lokalen statischen Variablen :) Vielen Dank für Ihre Hilfe! @ user58697 –