Anzeige:
Ergebnis 1 bis 14 von 14

Thema: [C]/[Gtk+] for-Fehler in Callback und allgemeine Fragen

  1. #1
    Registrierter Benutzer
    Registriert seit
    06.11.2009
    Ort
    Berlin
    Beiträge
    20

    Question [C]/[Gtk+] for-Fehler in Callback und allgemeine Fragen

    Hallo Community,

    ich wollte mal wieder Programmieren und dachte mir ich nehm meine alten Delphi-Beispiele aus der Schule und versuche mich mal in der GUI-Programmierung mit C.

    Hab mir dazu Gtk+ ausgesucht - hat mir gefühlsmäßig besser gefallen...

    Hab mir jetzt erst einmal mit Glade ne GUI gebaut und nach Tutorial das ganze zum laufen gebracht:
    Bildschirmfoto-Schere-Stein-Papier.png
    Bekomme es auch schon hin, das Button-clicked-Signal zu nutzen und dort abzufragen, welcher RadioButton gedrückt wird:
    Code:
    void on_button1_clicked ( GtkButton	*button1,
                              GSList   	*radio_list
                            ) {
    	GtkWidget *radio;
    	int i;
    	
    	for(i = 0; i < g_slist_length(radio_list); ++i) {
    		radio = g_slist_nth_data(radio_list, i);
    		/* radio != NULL check misses */
    		g_printf("%d. Durchlauf, ", i); /* Control of break */
    		if(gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(radio) )) {
    			g_printf("Button %d gedrueckt\n", 3-i);
    			break;
    		}
    	}
    	g_print("Kontrolle\n");
    }
    Jetzt zu meinem Problem:
    Wenn ich das so ausführe wird mir korrekt angezeigt, welcher RadioButton aktiv ist, allerdings wird die Kontrolausgabe nach der for-Schleife, sowohl vorher als auch hinterher ausgegeben:
    chris@Terra-Lap:Schere_Stein_Papier$ gcc -o game_SSP game_SSP.c $(pkg-configflags --libs gtk+-2.0 gmodule-2.0)
    chris@Terra-Lap:Schere_Stein_Papier$ ./game_SSP
    Kontrolle
    0. Durchlauf, 1. Durchlauf, 2. Durchlauf, Button 1 gedrueckt
    Kontrolle
    Kontrolle
    0. Durchlauf, 1. Durchlauf, Button 2 gedrueckt
    Kontrolle
    Kontrolle
    0. Durchlauf, Button 3 gedrueckt
    Kontrolle
    Wodurch tritt dieser Effekt auf? Ist das Normal?

    Dann noch ne Frage zur Benutzung von Gtk+:
    Wenn ich jetzt in dem Button-clicked callback
    • KI-Auswahl
    • Info-Ausgabe
    • Punkteveränderung
    setzen will, muss ich dann die betroffenen Objekte mit übergeben, oder kann ich einfach darauf zugreifen?

    THX 4 Help
    PS: Quellcode im Anhang

  2. #2
    Registrierter Benutzer Avatar von John W
    Registriert seit
    29.01.2010
    Beiträge
    211
    Falsches Forum, das gehört nach "Sparachen, Standard APIs".
    Ich kann mir gut vorstellen, dass Kontrolle zweimal ausgegeben wird, weil der Handler zweimal aufgerufen wird, wobei einmal einfach kein Button aktiv ist oder die Liste leer ist - lass dir bei Kontrolle auch mal g_slist_length(radio_list) ausgeben.
    Zudem würde ich int i in den for-Header packen, ist aber meist mehr eine Stilfrage:
    Code:
    for (int i = 0 ; ...)

  3. #3
    Registrierter Benutzer Avatar von sommerfee
    Registriert seit
    02.07.2006
    Beiträge
    1.603
    Zitat Zitat von crocodilechris Beitrag anzeigen
    Wodurch tritt dieser Effekt auf?
    Bei GTK+ wird der Callback bei Radiobuttons (und Radio-Menüpunkten) auch dann aufgerufen, wenn der Knopf deselektiert wird, d.h. bei einer Änderung gibt es immer zwei Callbacks.

    Ist das Normal?
    Ja.

    Liebe Grüße,
    Axel

  4. #4
    Registrierter Benutzer
    Registriert seit
    06.11.2009
    Ort
    Berlin
    Beiträge
    20
    Zitat Zitat von John W Beitrag anzeigen
    Zudem würde ich int i in den for-Header packen, ist aber meist mehr eine Stilfrage:
    Code:
    for (int i = 0 ; ...)
    Das wäre dann C99, versuche aber mich auf ANSI-C zu beschränken.
    Zitat Zitat von sommerfee Beitrag anzeigen
    Bei GTK+ wird der Callback bei Radiobuttons (und Radio-Menüpunkten) auch dann aufgerufen, wenn der Knopf deselektiert wird, d.h. bei einer Änderung gibt es immer zwei Callbacks.
    Ich weiß nicht obs was ändert, aber das ist nen Callback von nem GtkButton.
    Hab zur Kontrolle mal wie folgt den Code geändert (Länge an 2 Stellen ausgeben):
    Code:
    void on_button1_clicked ( GtkButton	*button1,
                              GSList   	*radio_list
                            ) {
    	GtkWidget *radio;
    	unsigned int i;
    	
    	for(i = 0; i < g_slist_length(radio_list); ++i) {
    		radio = g_slist_nth_data(radio_list, i);
    		/* radio != NULL check misses */
    		g_printf("Laenge: %d \n", g_slist_length(radio_list));
    		g_printf("%d. Durchlauf, ", i); /* Control of break */
    		if(gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(radio) )) {
    			g_printf("Button %d gedrueckt\n", 3-i);
    			break;
    		}
    	}
    	g_printf("Laenge2: %d \n", g_slist_length(radio_list));
    	g_print("Kontrolle\n");
    }
    Was mir dabei wieder auffällt:
    Die Kontrollausgaben nach der for-Schleife wird doppelt ausgegeben, die in der for-Schleife nur einmal:
    Laenge2: 0
    Kontrolle
    Laenge: 3
    0. Durchlauf, Button 3 gedrueckt
    Laenge2: 3
    Kontrolle
    Wenn der Callback zweimal aufgerufen würde, müsste doch auch die Schleife zweimal durchlaufen werden !?!?

  5. #5
    Registrierter Benutzer Avatar von sommerfee
    Registriert seit
    02.07.2006
    Beiträge
    1.603
    Offensichtlich wird da auch on_button1_clicked() mit "radio_list" = NULL aufgerufen, wieso und warum kann ich ohne weiteren Quelltext auch nicht sagen.

  6. #6
    Registrierter Benutzer
    Registriert seit
    06.11.2009
    Ort
    Berlin
    Beiträge
    20
    Hatte oben schon den Quelltext mit angehangen, aber hier nochmal im Anhang.

    Und danke für deine Mühen!

  7. #7
    Registrierter Benutzer Avatar von sommerfee
    Registriert seit
    02.07.2006
    Beiträge
    1.603
    Zitat Zitat von crocodilechris Beitrag anzeigen
    Hatte oben schon den Quelltext mit angehangen
    Oh, sorry, das hatte ich gar nicht gesehen

    Der Grund für das Verhalten ist in der Glade-Datei zu finden:
    Code:
    <signal name="clicked" handler="on_button1_clicked"/>
    Hier wird "button1" schon mit dem Handler "on_button1_clicked" verknüpft und hieraus resultiert der zusätzliche Aufruf mit radio_list = NULL und damit g_slist_length(radio_list) = 0.

    Wenn du also diese Verknüpfung aus der Glade-Datei herausnimmst, und nur diejenige im Quelltext game_SSP.c übrig läßt, sollte es besser funktionieren.

    Liebe Grüße,
    Axel

  8. #8
    Registrierter Benutzer
    Registriert seit
    06.11.2009
    Ort
    Berlin
    Beiträge
    20
    Vielen Dank!
    Das hat geholfen!

    Ich hab ja jetzt noch beim window1 das "destroy"-Signal mit gtk_main_quit drin.
    Würde es sich lohnen, dieses auch aus der Glade-Datei heraus zu nehmen und dafür dann folgenden Ausruf rauszuschmeißen?
    Code:
    /* Connect signals */
    gtk_builder_connect_signals( builder, NULL );
    Bzw. wenn ich alle Signale in Glade Vordefinieren wollen würde, müsste ich dann ein Struct bauen, dass alle meine Objekte & Widges beinhalten müsste, denen ich ein Signal zugewiesen habe?
    Wäre zwar "Arbeit", aber andererseits könnte ich eine Referenz davon immer jedem Callback mit Übergeben und könnte ohne Probleme auf meine Restlichen Widges zugreifen, oder?

  9. #9
    Registrierter Benutzer Avatar von John W
    Registriert seit
    29.01.2010
    Beiträge
    211
    Ein Callback sollte eig. im Sourcecode definiert werden, nicht in der Glade-Datei - da kann sonst die Sicherheit drunter leiden, zudem ist Debuggen schwieriger, da man dann ja auch "Code" in der Glade-Datei hat. Man kann es machen, dann aber konsequent und sollte sich über sämtliche Folgen im Klaren sein.

  10. #10
    Registrierter Benutzer
    Registriert seit
    06.11.2009
    Ort
    Berlin
    Beiträge
    20
    Falls ich mich wieder einmal unverständlich ausgedrückt habe (passiert mir öfter in Texten), dann nochmal klar:

    Es war nicht die Frage, nach dem auslagern des Callbacks ins Glade-File, sondern ob es lohnt die Signale im Glade-File zu definieren.
    Und ob ich in diesem Falle einen Struct definieren muss, in dem alle anzusprechenden Widges zusammengefasst werden.

  11. #11
    Registrierter Benutzer Avatar von John W
    Registriert seit
    29.01.2010
    Beiträge
    211
    Eigentlich war ich da ungenau.
    Signale würde ich im Sourcecode, nicht in der Glade-Datei verbinden.

  12. #12
    Registrierter Benutzer
    Registriert seit
    06.11.2009
    Ort
    Berlin
    Beiträge
    20
    Zitat Zitat von John W Beitrag anzeigen
    Signale würde ich im Sourcecode, nicht in der Glade-Datei verbinden.
    Okay, und dann kann ich auch die Argumente nachvollziehen:
    Zitat Zitat von John W Beitrag anzeigen
    da kann sonst die Sicherheit drunter leiden, zudem ist Debuggen schwieriger, da man dann ja auch "Code" in der Glade-Datei hat
    So, dann werd ich mich mal ranwagen, mir überlegen, ob ich alle Objekte oder Widgets die ich bearbeiten will in nen Struct verlagere, oder ne GSList übergebe, die ich dann wieder zerpflücke...
    Struct erscheint mir grad als sinnvollere Variante, wobei mir gerade auch union in den Kopf kommt, ... muss mir nochmal mein schlaues Buch vornehmen.

    Ohman, das ganze war in Delphi früher einfacher, aber jetzt lern ich mehr.

  13. #13
    Registrierter Benutzer Avatar von John W
    Registriert seit
    29.01.2010
    Beiträge
    211
    Das ist genau der Grund, warum ich meist Java nehm - da kommt man flott ans Ziel, und im Vergleich zu C und C++ ist die Performance auch ähnlich, wenn man in die Optimierungstrickkiste greift.
    Für kleine Hacks zwischendurch nehm ich sonst aber auch Bash oder Python, hat bisher meist immer gepasst.

  14. #14
    Registrierter Benutzer
    Registriert seit
    06.11.2009
    Ort
    Berlin
    Beiträge
    20

    Talking Jaja, warum einfach, wenn es auch schwer geht?

    [OFFTOPIC]
    Gut, aber als angehender Informatik-Lehrer sollte man schon mehr als eine Sprache und ein Konzept beherrschen.
    Ansonsten hab ich mir vorgenommen, das Projekt erst einmal in C zu realisieren, dann in Java und abschließend wollte ich mir noch Python beibringen und es damit dann auch noch realisieren.
    Vielleicht auch noch in Delphi, aber dann müsste ich Windows booten und das ist immer son Akt:
    Warten bis grub geladen ist und dann auch noch 2x Pfeiltaste-unten drücken, ...
    [/OFFTOPIC]

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •