Archiv verlassen und diese Seite im Standarddesign anzeigen : Gtk Callback mehrere Parameter übergeben
Also ich bin ziemlich neu in C eingestiegen und habe direkt mit Gtk Programmierung angefangen. Das hat bis jetzt auch ziemlich gut geklappt. Allerdings gibt es da ein Problem, das ich nicht so ganz aus der Welt schaffen kann.
Wie verbinde ich ein Signal eines Buttons mit einer Callback Funktion und übergebe der Funktion dabei mehrere Parameter? Ich finde dazu nichts in den Tutorials etc.
Wäre für Hilfe sehr Dankbar!
Hallo,
du hast bei den signals ja immer noch den Parameter: gpointer data
Darüber kannst du beliebeige Daten schicken. Allerdings kannst du nicht mehrere data Parameter haben, ich denke mal das ist das was du meinst. Wenn du mehrere Daten hast, dann mußt du dir halt was einfallen lassen. Wenn die Daten alle vom gleichen Typ sind, dann könntest du sie in einem array mitschicken, eine glist verwenden oder einen struct erstellen der deine Daten hält um mal ein paar Möglichkeiten zu nennen.
Gut Vielen Dank für die Antwort!
Dachte es gäbe vielleicht eine andere Möglichkeit. Dann werde ichs wohl als array machen :)
Hmm irgendwie klappt das Ganze aber noch nicht so, wie ich das gern hätte. Die wichtige Zeile sieht bei mir so aus:
buttonArrayProfile[0] = buttonImages; //erster Button Widget
buttonArrayProfile[1] = buttonChat; //zweiter Button Widget
g_signal_connect(G_OBJECT(buttonProfile), "pressed", G_CALLBACK(changeMenuActivity), (gpointer) buttonArrayProfile);
So lässt sich das auch kompilieren allerdings meint Gtk beim klick auf den Button folgenden Fehler ausgeben zumüssen:
(48tool:6704): GLib-GObject-WARNING **: invalid uninstantiatable type `(null)' in cast to `GtkToggleButton'
(48tool:6704): Gtk-CRITICAL **: gtk_toggle_button_set_active: assertion `GTK_IS_TOGGLE_BUTTON (toggle_button)' failed
RapidMax
21-10-2005, 17:17
Ich arbeiten üblicherweise mit einem Applikations-Objekt (GObject) bzw. struct in einfacheren Fällen. Dazu verwende ich während der Entwicklungszeit eine Magic-Number, die mir bei der Fehlersuche schon sehr oft geholfen hat. Hier ein Beispiel:
#define MAGIC 0x39a7b26f /* zufällig! */
typedef struct {
/* was auch immer gebraucht wird */
gint magic;
} Appdata;
void on_button_clicked(GtkWidget *button, gpointer user_data) {
Appdata *data = (Appdata*)user_data;
g_assert(data->magic == MAGIC);
/* hier weiter auf Felder in data zugreifen */
}
int main() {
Appdata data;
data.magic = MAGIC;
/* weiter initialisierungen von data */
gtk_init(argc, argv);
/* widgets erstellen, signale verbinden etc. */
g_signal_connect(G_OBJECT(button), "clicked",
G_CALLBACK(on_button_clicked), &data);
gtk_main()
/* cleanup */
return 0;
}
Wenn Appdata ein GObject ist, kannst du dir die Magic-number sparen, da wird sowieso bei jedem cast der Type überprüft.
Eine weitere Möglichkeit für die Übergabe von Daten ist g_object_set_data(). z.B. könnte man im Beispiel oben direkt Daten an button hängen:
g_object_set_data(G_OBJECT(button), "mydata", mydata);
Diese können dann in der Callback-Funktion wieder ausgelesen werden:
void on_button_clicked(GtkWidget *button, gpointer user_data) {
MyData *mydata = g_object_get_data(G_OBJECT(button), "mydata");
}
Gruss, Andy
@suicide
Ich weiß was du willst, und zwar in einer Callback-Funktion auf alle verfügbaren Elemente des Fenster zugreifen können.
Ich stand vor kurzem auch vor dem Problem, und dachte mir dass ich dazu die Callback-Funktionen mit entsprechenden Parametern ausstatten müsste, oder die Elemente global initialisiere. Da das beides völliger Schwachsinn ist und ich sowieso Glade verwende (wo das gar nicht funktioniert) habe ich mal in der Glade-Dokumentation gegoogelt und lookup_widget() gefunden. Diese Funktion gibt dir einen Zeiger auf ein Element deiner Wahl zurück, ähnlich der getElementById() in Javascript.
void
on_button1_released (GtkButton *button,
gpointer user_data)
{
GtkWidget *eingabefeld = lookup_widget(GTK_WIDGET(button), "entry1");
char *text = (char*)gtk_entry_get_text (GTK_ENTRY(eingabefeld));
g_print("g_print: %s\n", text);
}
lookup_widget durchsucht rekursiv den gesamten Elemente-Baum und gibt bei Fund den Zeiger darauf zurück.
Hinweis: Diese Funktion befindet sich in "support.c" und wird nur generiert, wenn das Häkchen bei "Unterstützende Funktionen erzeugen" gesetzt ist.
RapidMax
29-10-2005, 15:04
Wenn nicht die (veraltete) Code-Generierung von Glade verwendet wird, bietet das libglade API die Funktion glade_xml_get_widget() (http://developer.gnome.org/doc/API/libglade/gladexml.html#GLADE-XML-GET-WIDGET).
Alternativ kann auch eine Widget-Lookup-Funktion verwendet werden, die unabhängig von Glade arbeitet und nur die Introspection-Funktionen von Gtk verwendet. Ich verwende dafür eine Funktion basierend auf Gus Koppel
widget_find_by_name (http://www.spamkiller.bytechase.cx/democode/widget_find_by_name.c) (Original Postin (http://mail.gnome.org/archives/gtk-app-devel-list/2004-April/msg00282.html)).
Gruss, Andy
Die Funktion von Glade sieht aber nicht abhängig aus ;)
GtkWidget*
lookup_widget (GtkWidget *widget,
const gchar *widget_name)
{
GtkWidget *parent, *found_widget;
for (;;)
{
if (GTK_IS_MENU (widget))
parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
else
parent = widget->parent;
if (!parent)
parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey");
if (parent == NULL)
break;
widget = parent;
}
found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget),
widget_name);
if (!found_widget)
g_warning ("Widget not found: %s", widget_name);
return found_widget;
}
RapidMax
31-10-2005, 18:52
Das muss neuer sein, dem 2.6.8er aus Debian Sarge liegt noch die Variante bei, welche mit einer globalen Widget-Liste arbeitet.
Allerdings wird hier ein Datenfeld "GladeParentKey" benötigt, welches bei selbst händisch hinzugefügten Widgets kaum vorhanden sein wird.
Gruss, Andy
Wenn nicht die (veraltete) Code-Generierung von Glade verwendet wird, bietet das libglade API die Funktion glade_xml_get_widget() (http://developer.gnome.org/doc/API/libglade/gladexml.html#GLADE-XML-GET-WIDGET).
Soll man das wirklich verwenden. Hab mich nämlich schon gefragt warum man in glade3 keine Codegenerierung mehr hat. Entwerfe daher meine GUIs mit Glade3 und generiere sie dann mit Glade2. Verstehe einfach nicht wie das neue funktioniert!
MFG THE_ONE
Bei Glade3 stehen die Daten in einer XML-Datei die zur Laufzeit in GTK gerendet wird. Das hat den Vorteil, dass man die grafische Oberfläche ändern kann ohne neu zu compilieren.
Im C-Code nutzt du dann die libglade-Bibliothek und lädst die Glade-Datei ein.
// Lade und Parse Glade-XML-Datei
GladeXML *glade_app = glade_xml_new("test.glade", NULL, NULL);
Das erzeugt dir automatisch die Anwendung. Mit
// Beziehe Hauptfenster aus der GTK-Struktur
GtkWidget *window=glade_xml_get_widget(glade_app,"hauptfenster");
// Zeige Hauptfenster an
gtk_widget_show_all(window);
ziehst du dir dann die einzelnen Widgets aus der GladeXML-Struktur. Ähnlich wie bei getElementById in JavaScript.
Da macht den Code sauber und verständlich, sicherer und effektiver.
Ich hab nen glade3-Beispiel da, wenn du das mal brauchst.
Powered by vBulletin® Version 4.2.5 Copyright ©2025 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.