Callback Funktionsparameter
-
Hi,
ich sammle gerade meine ersten Erfahrungen mit GTK, und habe folgendes Problem:Ich möchte über einen Callback eine Funktion aufrufen die zwei Parameter aus zwei Textfeldern bekommen soll, aber irgendwie bekomm ich es nicht hin... Mit g_signal_connect kann ich ja mit dem letzten Parameter einen Parameter für die Callback-Funktion festlegen, und das klappt auch mit einem... Aber was mache ich denn nun wenn ich mehrere Parameter verwenden möchte?!
Hier einfach mal mein bisheriges Programm:
#include <stdio.h> #include <stdlib.h> #include <gtk/gtk.h> #include <string> using namespace std; // Wird beim Beenden des Programms aufgerufen void gtk_main_quit() { printf ("Quit Programm\n"); exit(0); } static void ggT(GtkWidget *widget, GtkWidget *aInput, GtkWidget *bInput) { gint a = (gint)gtk_entry_get_text(GTK_ENTRY(aInput)); gint b = (gint)gtk_entry_get_text(GTK_ENTRY(bInput)); printf ("Calculate GCD(%i, %i)\n", a, b); return; } int main(int argc, char *argv[]) { GtkWidget *window; GtkWidget *vbox, *hbox, *aHBox, *bHBox, *ggTHBox; GtkWidget *aInput, *bInput, *ggTInput; GtkWidget *closeButton, *calculateButton; GtkWidget *check; GtkWidget *programLabel, *aLabel, *bLabel, *ggTLabel; gint tmp_pos; gtk_init (&argc, &argv); // Fenstervariablen int windowWidth = 250; int windowHeight = 200; const gchar *windowTitle = "VDK - Aufgabe 03a"; // Fenster erstellen window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_widget_set_size_request (GTK_WIDGET (window), windowWidth, windowHeight); gtk_window_set_title (GTK_WINDOW (window), windowTitle); g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL); g_signal_connect_swapped (G_OBJECT (window), "delete_event", G_CALLBACK (gtk_widget_destroy), G_OBJECT (window)); // -------------------------------------------------------------- // Vertikales Layout erstellen vbox = gtk_vbox_new(FALSE, 0); gtk_container_add (GTK_CONTAINER(window), vbox); gtk_widget_show(vbox); // Programm Label erstellen, platzieren und anzeigen programLabel = gtk_label_new("Grösster gemeinsame Teiler"); gtk_box_pack_start (GTK_BOX (vbox), programLabel, TRUE, TRUE, 0); gtk_widget_show(programLabel); // -------------------------------------------------------------- // a Horizontales Layout erstellen aHBox = gtk_hbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (vbox), aHBox); gtk_widget_show(aHBox); // a Label erstellen, platzieren und anzeigen aLabel = gtk_label_new("a: "); gtk_box_pack_start (GTK_BOX (aHBox), aLabel, TRUE, TRUE, 0); gtk_widget_show(aLabel); // a Eingabefeld erstellen aInput = gtk_entry_new (); // Max. Zeichenlänge auf 10 beschränken gtk_entry_set_max_length (GTK_ENTRY (aInput), 10); //g_signal_connect (G_OBJECT (aInput), "activate", G_CALLBACK (ggT), (gpointer) aInput); gtk_entry_set_text (GTK_ENTRY (aInput), "12"); gtk_box_pack_start (GTK_BOX (aHBox), aInput, TRUE, TRUE, 0); gtk_widget_show (aInput); // -------------------------------------------------------------- // b Horizontales Layout erstellen bHBox = gtk_hbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (vbox), bHBox); gtk_widget_show(bHBox); // b Label erstellen, platzieren und anzeigen bLabel = gtk_label_new("b: "); gtk_box_pack_start (GTK_BOX (bHBox), bLabel, TRUE, TRUE, 0); gtk_widget_show(bLabel); // b Eingabefeld erstellen bInput = gtk_entry_new (); // Max. Zeichenlänge auf 10 beschränken gtk_entry_set_max_length (GTK_ENTRY (bInput), 10); //g_signal_connect (G_OBJECT (bInput), "activate", G_CALLBACK (ggT), (gpointer) bInput); gtk_entry_set_text (GTK_ENTRY (bInput), "40"); /*tmp_pos = GTK_ENTRY (bInput)->text_length; gtk_editable_insert_text (GTK_EDITABLE (bInput), " world", -1, &tmp_pos); gtk_editable_select_region (GTK_EDITABLE (bInput), 0, GTK_ENTRY (bInput)->text_length); */ gtk_box_pack_start (GTK_BOX (bHBox), bInput, TRUE, TRUE, 0); gtk_widget_show (bInput); // -------------------------------------------------------------- // ggT Horizontales Layout erstellen ggTHBox = gtk_hbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (vbox), ggTHBox); gtk_widget_show(ggTHBox); // ggT Label erstellen, platzieren und anzeigen ggTLabel = gtk_label_new("ggT: "); gtk_box_pack_start (GTK_BOX (ggTHBox), ggTLabel, TRUE, TRUE, 0); gtk_widget_show(ggTLabel); // ggT Eingabefeld erstellen ggTInput = gtk_entry_new (); // Max. Zeichenlänge auf 10 beschränken gtk_entry_set_max_length (GTK_ENTRY (ggTInput), 10); //g_signal_connect (G_OBJECT (ggTInput), "activate", G_CALLBACK (ggT), (gpointer) ggTInput); // Textfeld nicht editierbar machen gtk_editable_set_editable (GTK_EDITABLE (ggTInput), FALSE); gtk_box_pack_start (GTK_BOX (ggTHBox), ggTInput, TRUE, TRUE, 0); gtk_widget_show (ggTInput); // -------------------------------------------------------------- // Berechnen Button calculateButton = gtk_button_new_with_label("ggT berechnen"); g_signal_connect (G_OBJECT (calculateButton), "clicked", G_CALLBACK (ggT), G_OBJECT (window)); gtk_box_pack_start (GTK_BOX (vbox), calculateButton, TRUE, TRUE, 0); //GTK_WIDGET_SET_FLAGS (calculateButton, GTK_CAN_DEFAULT); //gtk_widget_grab_default (calculateButton); gtk_widget_show (calculateButton); // Schliessen Button closeButton = gtk_button_new_from_stock (GTK_STOCK_CLOSE); g_signal_connect_swapped (G_OBJECT (closeButton), "clicked", G_CALLBACK (gtk_widget_destroy), G_OBJECT (window)); gtk_box_pack_start (GTK_BOX (vbox), closeButton, TRUE, TRUE, 0); GTK_WIDGET_SET_FLAGS (closeButton, GTK_CAN_DEFAULT); gtk_widget_grab_default (closeButton); gtk_widget_show (closeButton); gtk_widget_show (window); gtk_main(); return 0; }
Freue mich über jeden Tip
-
Hi,
die Lösung deines Problems ist simpel: Du kapselst mehrere Werte mit einem struct:
typedef struct { int alter; char vorname[30]; } Foo;
MfG
GPC
-
Hi...
Danke für Deine Antwort.
Macht man es denn so im Allgemeinen?
Ich war jetzt auf die Idee gekommen die Variablen die ich brauche einfach global zu halten. Was bei späteren grösseren Projekten vielleicht unschön wird.
Bei vielen Funktionen mit unterschiedlichen Parametern jedesmal die benötigten Parameter in eine Struktur zu verpacken ist vielleicht eine Lösung, aber auch nicht das Eleganteste oder sehe ich das falsch.Für weitere Tipps bin ich immer zu haben
-
startupboy schrieb:
Hi...
Danke für Deine Antwort.
Macht man es denn so im Allgemeinen?Zumindest ich mach das so im Allgemeinen. Du kannst dir aber auch gerne OpenSource Programme, die mit GTK+ geschrieben wurden, ansehen und wirst da "Ähnlichkeiten" finden
Ich war jetzt auf die Idee gekommen die Variablen die ich brauche einfach global zu halten.
Schlechte Idee.
Was bei späteren grösseren Projekten vielleicht unschön wird.
Mit Sicherheit.
Bei vielen Funktionen mit unterschiedlichen Parametern jedesmal die benötigten Parameter in eine Struktur zu verpacken ist vielleicht eine Lösung, aber auch nicht das Eleganteste oder sehe ich das falsch.
Na ja, es ist eine Art "OOC"
Objektorientierte Programmierung in C. Man gibt eben seine Instanzen rum, so wie man's in C++ auch macht. GTK+ versteht sich ja auch als objektorientiertes Toolkit (dafür steht auch das +; das es in C geschrieben ist, ist egal).
Und mir persönlich liegt dieser Stil sehr.
MfG
GPC
-
Stimmt schon...
Vielleicht sollte ich mein Programm mehr auf OOP ausrichten, und dann einfach ein Objekt übergeben oder Deinen Tipp mit der Struktur befolgen.