Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Parameter in GTK-Callback-Funktionen

14 views
Skip to first unread message

Michael Röhn

unread,
Feb 9, 2002, 6:00:38 PM2/9/02
to
Hallo,

ich möchte in einer GTK-Anwendung Text von einem TextView zu einem anderen
durch drücken eines Buttons bewirken. Dadurch muß ich der Callback-Funktion
aber zwei Widgets übergeben, wobei ich aber nur einen gpointer übergeben
kann. Auf die Idee, eine Struktur zu übergeben bin ich auch schon gekommen,
aber das klappt irgendwie nicht.
Hat jemand irgendwo Beispielcode parat, wie man mehr als einen Parameter an
eine Callback-Funktion übergibt?

MfG
- Michael Röhn

Andreas Baier

unread,
Feb 10, 2002, 9:07:50 AM2/10/02
to
Michael Röhn wrote:

> Dadurch muß ich der Callback-Funktion aber zwei Widgets übergeben, wobei
> ich aber nur einen gpointer übergeben kann.

Das selbe Problem hatte ich auch, ich hab das mit einem Widget-Array
gelöst, das ich übergebe. Ist wahrscheinlich nicht die beste Methode, aber
es funktioniert.
Hier ein Auszug aus meinem Code:

------schnipp----------

/*Other Widgets*/

GtkWidget *mehrere[3];
GtkWidget *zwei[2];

/**********************************************************/
/*OTHER(Übergebe Widgets um z.B: Werte daraus zu beziehen)*/
/**********************************************************/

mehrere[0]=GTK_WIDGET(label_dez);
mehrere[1]=GTK_WIDGET(entry);
mehrere[2]=GTK_WIDGET(spin);

zwei[0]=GTK_WIDGET(label_bin);
zwei[1]=GTK_WIDGET(entry_btoi);

/************/
/*Callbacks */
/************/

gtk_signal_connect(GTK_OBJECT(but_berechne), "clicked",
GTK_SIGNAL_FUNC(rechne_itob), mehrere);
gtk_signal_connect(GTK_OBJECT(but_btoi), "clicked",
GTK_SIGNAL_FUNC(rechne_btoi), zwei);

------schnapp----------

Wenn dir das nicht reicht, auf
http://www.linuxhilfen.org/c/umrechner.tar.gz ist der komplette Code zu
finden.

Michael Röhn

unread,
Feb 10, 2002, 9:42:24 AM2/10/02
to
Danke sehr, das hat geholfen, das Problem mehr oder weniger zu umgehen. Ich
frag mich allerdings ob das die übliche Methode ist. Ich hab schon oft
gelesen, daß man solche Probleme üblicherweise mit structs löst, aber
nirgends war mal ein Beispiel.
Die Sache mit den Arrays ist gewitzt ;), aber sowas muß doch auch mit
structures möglich sein, oder nicht? Es muß doch möglich sein, an eine
Callback-Funktion mehr als 1 Parameter zu übergeben, ohne auf ein Array
zurückgreifen zu müssen. - Genau das geht bei mir nicht so einfach.

MfG
Michael Röhn

Markus Lausser

unread,
Feb 10, 2002, 9:43:58 AM2/10/02
to

Man muss natuerlich beachten, dass die uebergebenen Daten beim
Aufruf des Handlers noch verfuegbar sind (dynamisch allokiert,
oder global deklariert).

Markus.

Andreas Baier

unread,
Feb 10, 2002, 11:21:25 AM2/10/02
to
On Sun, 10 Feb 2002 15:42:24 +0100, Michael Röhn wrote:

> Danke sehr, das hat geholfen, das Problem mehr oder weniger zu umgehen. Ich
> frag mich allerdings ob das die übliche Methode ist.

bestimmt nicht, aber die Sache mit den Structs hat auch bei mir nicht
recht funktioniert. Lag aber vermutlich an falschen Pointern o.ä.
Möglich ist es aber bestimmt

--
bait...@gmx.net
www.linuxhilfen.org

Andreas Baier

unread,
Feb 10, 2002, 11:23:50 AM2/10/02
to
On Sun, 10 Feb 2002 15:43:58 +0100, Markus Lausser wrote:

>
> Man muss natuerlich beachten, dass die uebergebenen Daten beim
> Aufruf des Handlers noch verfuegbar sind (dynamisch allokiert,
> oder global deklariert).

Sind sie das in meinem Beispiel nicht? Ich gehe
stillschweigend davon aus, das die Widgets (wenn sie nicht wieder
explizit freigegeben werden) bis zum Programmende bestehenbelieben.


--
bait...@gmx.net
www.linuxhilfen.org

Markus Lausser

unread,
Feb 10, 2002, 1:46:38 PM2/10/02
to
On Sun, 10 Feb 2002 17:21:25 +0100, Andreas Baier wrote:
> On Sun, 10 Feb 2002 15:42:24 +0100, Michael Röhn wrote:
>
> > Danke sehr, das hat geholfen, das Problem mehr oder weniger zu umgehen. Ich
> > frag mich allerdings ob das die übliche Methode ist.
>
> bestimmt nicht, aber die Sache mit den Structs hat auch bei mir nicht
> recht funktioniert. Lag aber vermutlich an falschen Pointern o.ä.
> Möglich ist es aber bestimmt

Es ist ansichtssache, ob Du das nun mit arrays oder mit structs machst.
Wie aber schon gesagt: Du musst sowohl array als auch struct dynamisch
(oder auch global, ggf. mit static) allokieren, und nicht nur lokal.

Ne andere Moeglichkeit ist, dass die callback function selbst
die Widgets ermittelt, so dass Du sie nicht mehr uebergeben musst.

Man kann z.B. einem widget datenpointer zuweisen:
gtk_object_set_data(GTK_OBJECT(widget), "key_word1", ref_widget1);
gtk_object_set_data(GTK_OBJECT(widget), "key_word1", ref_widget2);
gtk_object_set_data(GTK_OBJECT(widget), "key_word1", ref_widget3);

In der callback function von <widget> kannste dann diese pointer
wieder abrufen mit:
ref_widget1 = gtk_object_get_data(GTK_OBJECT(widget), "key_word1");
ref_widget2 = gtk_object_get_data(GTK_OBJECT(widget), "key_word2");
ref_widget3 = gtk_object_get_data(GTK_OBJECT(widget), "key_word3");

Markus.

Michael Röhn

unread,
Feb 10, 2002, 4:26:27 PM2/10/02
to
Es besteht noch ein winziges Problem, wie es scheint.
Ich hab mich der Array-Methode bedient und folgendes versucht:

Eine Callback-Funktion soll ein Array mit 2 Elementen entgegennehmen, was
jeweils 2 Widgets enthält. Diese beiden Widgets sind vom Typ "GtkWidget *"
und werden mit "gtk_text_view_new" erzeugt. (GTK+ 2.0 -> ersetzt GtkText)

Code:
---
void CopyBuffers (GtkWidget *widget, GtkWidget *widgets[2]){
if(GTK_IS_TEXT_VIEW(GTK_TEXT_VIEW(widgets[0])))
fprintf(stderr,"Okay\n");
else
fprintf(stderr,"Nicht Okay\n");
}

main (...){
...
GtkWidget *feld[2];
GtkWidget *view1, *view2, *button_copy;
...
feld[0] = view1;
feld[1] = view2;
...
gtk_signal_connect( GTK_OBJECT(button_copy), "clicked",
GTK_SIGNAL_FUNC(CopyBuffers), feld);
...
gtk_main();
...
}
---

Schlußendlich soll die Callback-Funktion einen TextView-Inhalt zu einem
anderen kopieren. Wenn ich im obigen Code-Beispiel nun aber den Button
"button_copy" drücke, dann wird mir in der Standard-Fehlerausgabe "Nicht
okay" ausgegeben und noch zusätzlich:
---
GLib-GObject-WARNING **: invalid cast from (NULL) pointer to `GtkTextView'
---
Ich hab doch aber niemals von NULL irgendwohin gecastet, sondern nur von
GtkWidget nach GtkTextView, wo also ist dort der Fehler zu finden?

Vielen Dank...
Michael Röhn

Michael Röhn

unread,
Feb 10, 2002, 5:19:59 PM2/10/02
to
Sorry, der Fehler war peinlich.
Ich hab das Feld gefüllt bevor überhaupt die eigentlichen Objekte erstellt
wurden.

MfG
Michael

Markus Lausser

unread,
Feb 10, 2002, 5:33:10 PM2/10/02
to

Hm, ist da hier mein Post abhandengekommen? Also nochmal:
Die Widgets bleiben bestehen, ja, aber das array nicht (wenn es nicht
grade in main() steht). Das ist weg, sobald Du die funktion verlaesst,
in der Du den signal handler setzt (ein static wuerde hier abhilfe
schaffen).

Es kann aber durchaus sein, dass es trotzdem (zufaellig) funktioniert,
weil der (schon freigegebene) speicher des arrays auch spaeter noch
die richtigen Daten enthaelt. Ist aber wie gesagt dann Zufall.

Markus.

Markus Lausser

unread,
Feb 10, 2002, 5:42:35 PM2/10/02
to

Wenn Du das wirklich alles in main() machst, wie oben beschrieben, dann
faellt mir als Grund nur ein, dass view12 zum Zeitpunkt der Zuweisung
eben NULL enthalten hat. Wenn das nicht in main() passiert, dann ist
dieser code fehlerhaft (siehe meine anderen posts).

Ich persoenlich wuerde die Daten auch mit gtk_object_set_data()
uebergeben (deprecated in GTK2.0 -> stattdessen g_object_set_data())
und mit gtk_object_get_data() wieder auslesen (GTK2.0: g_object_get_data())

Markus.

Michael Röhn

unread,
Feb 11, 2002, 5:19:44 AM2/11/02
to
> Ich persoenlich wuerde die Daten auch mit gtk_object_set_data()
> uebergeben (deprecated in GTK2.0 -> stattdessen g_object_set_data())
> und mit gtk_object_get_data() wieder auslesen (GTK2.0:
> g_object_get_data())

Hast recht. Diese Methode ist weitaus flexibler und sicherer, was den
Speicher anbelangt.
Mal was anderes: Gtk+ 2.0 scheint entweder ein Problem mit Accelerators zu
haben oder hat das Konzept total umgestellt. Die Accelerator-Funktionen,
die bei Gtk1.2 noch gingen, funktionieren nun nicht mehr. So habe ich z.B.
die Kombination "Strg+Q" zum Senden eines "delete_event" an das
Hauptfenster. Dies klappt nun nicht mehr. Der Compiler beschwert sich
nicht, aber während der Laufzeit kommt folgender Fehler:

Gtk-WARNING **: gtkwidget.c:2612:gtk_widget_add_accelerator(): widget
`GtkWindow' has no activatable signal "delete_event" without arguments

Muß ich noch irgendwo extra vereinbaren, daß GtkWindow auf mein
delete-Event reagiert? (bisher war das nicht so)

MfG
Michael Röhn

Markus Lausser

unread,
Feb 11, 2002, 8:59:17 AM2/11/02
to

Ich habe leider mit GTK2.0 keine Erfahrung, obiges habe ich aus der online
Referenz..Schau doch mal auf www.gtk.org, vielleicht findest Du dort ja
in der Referenz was darueber, wenn nicht, dann gibts da noch die
gtk+ mailinglists, dort kann man dir sicher weiterhelfen..

Markus.

0 new messages