Anzeige:
Ergebnis 1 bis 10 von 10

Thema: for(i) g_signal_connect( ..., &i)

  1. #1
    Registrierter Benutzer
    Registriert seit
    02.08.2008
    Beiträge
    177

    for(i) g_signal_connect( ..., &i)

    Hi,

    ich habe einmal wieder ein kleineres Problem bei Gtk. Und zwar benötige ich in der G_Callback Funktion die Elementnummer eines malloc Array`s. Mein Problem ist der gpointer von g_signal_connect. Bei dem Gui-Aufruf wurde die Schleife schon komplett durchlaufen und somit wird bei jedem Knopfdruck die letzte Zahl der Schleife also i=4 übertragen und ein Speicherleck verursacht.

    Version 1:
    Code:
    void c_clicked(GtkButton *button, gpointer user_data){
          int *i = user_data;
          printf(*i=%i\n",*i);
          ...
          extern int *Ary; 
          printf(Ary[*i]=%i\n",Ary[*i]);
    }
     
    int main(){
        ...
       GtkWidget c_button[4];
    
       for(int i=0,i<4, i++){
            c_button[i] = gtk_button_new_with_label ("text");
            g_signal_connect (c_button[i], "clicked", G_CALLBACK (b_clicked), &i);
       }
    
      return 0;
    }
    Version 2:
    Code:
    typedef struct{
       int id;
       int *Ary;  // ->malloc
    } Data;
    
    
    void c_clicked(GtkButton *button, gpointer user_data){
          Data *data = user_data;
          printf(%i\n",data->Ary[data->id]);
    }
    
    void my_func( int anz, int *array){
         ...
        Data data[anz];
    
       GtkWidget c_button[anz];
    
       for(int i=0,i<=anz, i++){
            data[i].id= i;
            data[i].Ary = array;
    
            c_button[i] = gtk_button_new_with_label ("text");
            g_signal_connect (c_button[i], "clicked", G_CALLBACK (b_clicked), &data[i]);
       }
    
      return 0;
    }
    Habe es jetzt direkt mit der Addresse des Arrayementes versucht also:
    Code:
            g_signal_connect (c_button[i], "clicked", G_CALLBACK (b_clicked), &array[i]);
    und funktioniert, doch bringt Problem der konstanten Adresse mit sich.

    Vielen Dank für Eure Unterstützung!
    dml
    Geändert von dml (14-10-2013 um 18:51 Uhr) Grund: i<4

  2. #2
    Registrierter Benutzer
    Registriert seit
    23.05.2004
    Beiträge
    592
    Code:
    GtkWidget c_button[4];
    
       for(int i=0,i<=4, i++){
            c_button[i] = gtk_button_new_with_label ("text");
    Mit Gtk kenne ich mich nicht aus. Aber so wie du die Schleife durchläufst wirst du c_button mit 4 indizieren. Das ist verboten - die gültigen Indices sind 0, 1, 2, 3.

    Die kanonische Form für Zählschleifen ist
    Code:
    for(count i = 0; i != limit; ++i)
    count/limit sind natürlich nur Stellvertreter.

    Wenn du C++ in der 2011er Version zur Verfügung hast gerne auch wie in
    Code:
    for(widget w : array) { mach_was_mit(w); }

  3. #3
    Registrierter Benutzer
    Registriert seit
    02.08.2008
    Beiträge
    177
    Ups, ausversehen übersehen, ich habe es geändert. Mein Problem ist, das ich nur als Parameter eine Adresse übergeben kann &i und keine Werte i aufgrund des gpointers. Aber danke das Du Dir die Mühe gemacht hast und mir helfen wolltest und ich so unsauberen Quelltext gepostet habe.

  4. #4
    Registrierter Benutzer Avatar von sommerfee
    Registriert seit
    02.07.2006
    Beiträge
    1.604
    Zitat Zitat von dml Beitrag anzeigen
    Mein Problem ist, das ich nur als Parameter eine Adresse übergeben kann &i und keine Werte i aufgrund des gpointers.
    Übergebe GINT_TO_POINTER(i) stattdessen. In dem Signal-Handler kannst du dann den Pointer mittels
    Code:
    int i = GPOINTER_TO_INT(user_data);
    wieder in einen Integerwert zurückwandeln.

    Siehe auch: https://developer.gnome.org/glib/sta...on-Macros.html
    Geändert von sommerfee (14-10-2013 um 20:05 Uhr)

  5. #5
    Registrierter Benutzer
    Registriert seit
    02.08.2008
    Beiträge
    177
    Muss mich vielmals bei Dir Bedankem sommerfee! Dein Tip hat mir sehr geholfen. Kann jetzt mit extern int *Ary; weiterarbeiten, was zwar ein ungeliebter Gast in Gui Entwicklungen ist, wegen der Hauptschleife (gtk_main()), doch kann ich mir jetzt erst einmal sicher sein.

    Vielen Dank für Deine Bemühung mir zu Helfen.
    Geändert von dml (15-10-2013 um 19:37 Uhr)

  6. #6
    Registrierter Benutzer
    Registriert seit
    02.08.2008
    Beiträge
    177
    Habe jetzt das gute Alte:
    Code:
    gtk_widget_set_object_name();
    gefunden.

    Code:
    void c_clicked(GtkButton *button, gpointer user_data){
          Int* array = user_data;
          int value = array[atoi(gtk_widget_get_object_name(button))];
          printf(%i\n", value);
    }
    
    void my_func( int anz, int *array){
         ...
       char[2] buffer;
    
       GtkWidget c_button[anz];
    
       for(int i=0,i<=anz, i++){
            sprintf(buffer,"%i",i);
            c_button[i] = gtk_button_new_with_label ("textt);
            gtk_widget_set_object_name(buffer);
            g_signal_connect (c_button[i], "clicked", G_CALLBACK (b_clicked), array);
       }
    
      return 0;
    }
    Und kann auf extern verzichten.
    Geändert von dml (20-10-2013 um 14:20 Uhr)

  7. #7
    Registrierter Benutzer Avatar von sommerfee
    Registriert seit
    02.07.2006
    Beiträge
    1.604
    Warum übergibst du nicht einfach array+i statt array?

    Code:
    void c_clicked(GtkButton *button, gpointer user_data){
          Int* array_i = user_data;
          int value = *array_i;
          printf(%i\n", value);
    }
    
    void my_func( int anz, int *array){
         ...
       GtkWidget c_button[anz];
    
       for(int i=0,i<=anz, i++){
            c_button[i] = gtk_button_new_with_label ("text");
            g_signal_connect (c_button[i], "clicked", G_CALLBACK (b_clicked), array + i);
       }
    
      return 0;
    }

  8. #8
    Registrierter Benutzer
    Registriert seit
    02.08.2008
    Beiträge
    177
    Coole Idee, kannte ich noch nicht, vor allem da set_object_name eigentlich nicht zur Wertübergabe gedacht ist. Ich werde es morgen gleich ausprobieren, vor allem, ob es auch mit struct's funktioniert.Danke.

  9. #9
    Registrierter Benutzer Avatar von sommerfee
    Registriert seit
    02.07.2006
    Beiträge
    1.604
    BTW:
    Code:
    for(int i=0,i<=anz, i++){
    ist (immer noch) falsch, es muß
    Code:
    for(int i=0,i<anz, i++){
    heißen. (Siehe auch http://www.mrunix.de/forums/showpost...98&postcount=2 )

  10. #10
    Registrierter Benutzer
    Registriert seit
    02.08.2008
    Beiträge
    177
    Na an dem Quellcode war so einiges falsch. Ich wollte nicht den gesamten ursprünglichen verwenden. Hätten diesen aber vorher testen müssen.

Lesezeichen

Berechtigungen

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