IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

GTK+ avec C & C++ Discussion :

Petit Problème dans une GTK-Table


Sujet :

GTK+ avec C & C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 16
    Points : 11
    Points
    11
    Par défaut Petit Problème dans une GTK-Table
    à tous!

    Voilà, j'aimerais tout simplement créer une GTK-Table, composée de 6 boutons numérotés, tels que lorsque l'on clique dessus, il puisse apparaître une fenêtre réponse contenant le numéro correspondant au bouton.

    Voici ci dessous le source que j'ai codé...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <gtk/gtk.h>
     
    #define N 6
     
    //Cette procédure affiche une fenêtre affichant le numéro du bouton correspondant
    void fenetreReponse (int n); 
     
    int main (int argc, char **argv) {
     
        GtkWidget *pFenetre, 
                  *pTable,
                  *pBouton [N];
     
        gchar *c;
     
        gtk_init (&argc, &argv);
     
        //Création et définition de la fenêtre globale
        pFenetre = gtk_window_new (GTK_WINDOW_TOPLEVEL);
        gtk_window_set_default_size (GTK_WINDOW(pFenetre), 180, 300);
        gtk_window_set_position (GTK_WINDOW(pFenetre), GTK_WIN_POS_CENTER);
        gtk_window_set_title (GTK_WINDOW(pFenetre), "Tableau de Valeurs");
     
        //Création de la table 7 lignes et 1 colonne
        pTable = gtk_table_new (6, 1, TRUE);
     
        int i;
        for (i=0; i<N; i++) {
     
            //Création de chaque bouton
            g_sprintf (c, "%d", i+1);
            pBouton[i] = gtk_button_new_with_label (c);
     
            //Insertion de chaque bouton dans la table
            gtk_table_attach_defaults (GTK_TABLE(pTable), pBouton[i], 0, 1, i, i+1);
     
            //Connexion de chaque bouton au signal "clicked"
            g_signal_connect (G_OBJECT(pBouton[i]), "clicked", G_CALLBACK(fenetreReponse), &i); }
     
        //Insertion de le table dans la fenetre
        gtk_container_add (GTK_CONTAINER(pFenetre), pTable);
     
        //Connexion de la fenêtre au signal "destroy"
        g_signal_connect (G_OBJECT(pFenetre), "destroy", G_CALLBACK(gtk_main_quit), NULL);
     
        //Affichage de la fenêtre globale et tout son contenu
        gtk_widget_show_all (pFenetre);
     
        gtk_main ();
     
        return EXIT_SUCCESS;
    }
     
    void fenetreReponse (int n) {
     
         GtkWidget *pFenetre, *pLabel;
         gchar *c;
     
         //Création de la fenêtre d'affichage
         pFenetre = gtk_window_new (GTK_WINDOW_TOPLEVEL);
         gtk_window_set_default_size (GTK_WINDOW(pFenetre), 150, 100);
         gtk_window_set_position (GTK_WINDOW(pFenetre), GTK_WIN_POS_CENTER);
         gtk_window_set_title (GTK_WINDOW(pFenetre), g_locale_to_utf8 ("Fenêtre réponse", -1, NULL, NULL, NULL));
     
         //Création du label et insertion dans la fenêtre
         g_sprintf (c, "%ld", n);
         pLabel = gtk_label_new (c); 
         gtk_container_add (GTK_CONTAINER(pFenetre), pLabel);
     
         //Affichage de la fenêtre
         gtk_widget_show_all (pFenetre);
    }

    Il compile très bien, mais à l'exécution, lorsque je clique sur n'importe quel bouton, la fenêtre résultat m'affiche un nombre au hasard (comme par exemple: 11315679)...

    Je ne sais pas d'où vient le problème (...peut-etre de ma fonction CALLBACK...)

    Quelqu'un pourrait-il m'aider s'il vous plaît? Je suis désespéré....
    Merci d'avance...

  2. #2
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Salut et bienvenue sur les forums de developpez.com


    Comme je le répète sans cesse sur ce forum, les callback ont des signatures précises suivant les widgets et leurs signaux qu'il convient de respecter, ce que tu ne faits pas ! Ton callback doit avoir la signature:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void fenetreReponse (GtkWidget * wid, gpointer data);
    Ainsi qu'il est précisé dans ton cours et surtout dans la ref officielles de GTK+ qu'il convient de consulter au préalable !

    Il est également de bon ton de ne pas faire de GtkWindow pour simplement afficher un message, tel qu'il est écrit dans tes cours de GTK+ (au pire des cas lis celui-ci pour avoir les bases: http://gtk.developpez.com/cours/gtk2/), il y'a la possibilité de créer un GtkDialog qui est prévu à cet effet !

    Voici ton code corrigé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    #include <stdlib.h>
    #include <stdio.h>
    #include <gtk/gtk.h>
    #include <glib/gprintf.h>
     
    #define N 6
     
    //Cette procédure affiche une fenêtre affichant le numéro du bouton correspondant
    void fenetreReponse (GtkWidget * wid, gpointer data);
     
    int main (int argc, char **argv) {
     
        GtkWidget *pFenetre,
                  *pVBox,
                  *pBouton [N];
     
    /* Franck.H - Il faut un tableau statique ou bien dynamique mais l'adresse
                  doit etre valide, ce qui ne l'est pas dans ton cas. */
        /*gchar *c;*/
        gchar c[5];
     
        gtk_init (&argc, &argv);
     
        //Création et définition de la fenêtre globale
        pFenetre = gtk_window_new (GTK_WINDOW_TOPLEVEL);
        gtk_window_set_default_size (GTK_WINDOW(pFenetre), 180, 300);
        gtk_window_set_position (GTK_WINDOW(pFenetre), GTK_WIN_POS_CENTER);
        gtk_window_set_title (GTK_WINDOW(pFenetre), "Tableau de Valeurs");
     
    /* Franck.H - Inutile ici, un GtkVBox est nettement mieux si reste sur
                  une seule colonne. */
        //Création de la table 7 lignes et 1 colonne
        /*pTable = gtk_table_new (6, 1, TRUE);*/
        pVBox = gtk_vbox_new (TRUE, 0);
     
    /* Franck.H - Utilise les types de la GLIB, c'est mieux. */
        gint i;
        for (i=0; i<N; i++) {
            //Création de chaque bouton
            g_sprintf (c, "%d", i+1);
            pBouton[i] = gtk_button_new_with_label (c);
     
            //Insertion de chaque bouton dans la table
            /*gtk_table_attach_defaults (GTK_TABLE(pTable), pBouton[i], 0, 1, i, i+1);*/
            gtk_box_pack_start (GTK_BOX (pVBox), pBouton[i], TRUE, TRUE, 0);
     
            //Connexion de chaque bouton au signal "clicked"
            g_signal_connect (G_OBJECT(pBouton[i]), "clicked", G_CALLBACK(fenetreReponse), &i);
        }
     
        //Insertion de le table dans la fenetre
        gtk_container_add (GTK_CONTAINER(pFenetre), pVBox);
     
        //Connexion de la fenêtre au signal "destroy"
        g_signal_connect (G_OBJECT(pFenetre), "destroy", G_CALLBACK(gtk_main_quit), NULL);
     
        //Affichage de la fenêtre globale et tout son contenu
        gtk_widget_show_all (pFenetre);
        gtk_main ();
     
        return EXIT_SUCCESS;
    }
     
    void fenetreReponse (GtkWidget * wid, gpointer data) {
     
         GtkWidget *pFenetre, *pLabel;
    /* Franck.H - Il faut un tableau statique ou bien dynamique mais l'adresse
                  doit etre valide, ce qui ne l'est pas dans ton cas. */
        /*gchar *c;*/
        gchar c[5];
     
         gint * n = data;
         g_printf ("%d\n", *n);
     
     
    /* Franck.H - Creation d'une boite de dialogue, bien mieux ici. */
         pFenetre = gtk_dialog_new_with_buttons (
             "Fenetre de reponse...",
             NULL,
             GTK_DIALOG_MODAL,
             GTK_STOCK_OK, GTK_RESPONSE_OK,
             NULL
         );
     
         //Création du label et insertion dans la fenêtre
         g_sprintf (c, "%d", *n);
         pLabel = gtk_label_new (c);
         gtk_box_pack_start (
             GTK_BOX (GTK_DIALOG (pFenetre)->vbox), pLabel, TRUE, TRUE, 0
         );
         gtk_widget_show_all (GTK_DIALOG (pFenetre)->vbox);
     
     
         //Affichage de la fenêtre
         switch (gtk_dialog_run (GTK_DIALOG (pFenetre)))
         {
            case GTK_RESPONSE_OK:
            default:
             break;
         }
     
    /* Franck.H - Pas oublier de detruire la boite de dialogue. */
         gtk_widget_destroy (pFenetre);
     
         (void) wid;
    }
    Un seul problème qui persiste et que je te laisse, c'est le nombre, étant donné que tu passes l'adresse de i à tes callback et cette variable étant modifiée à chaque itération de la boucle, tu auras la même valeut pour chacun de tes boutons, ce qui est tout à fait normal

    Je te laisse résoudre ce problème... rien de bien compliqué mais il ne faut pas passer par i. Une piste, tu as un tableau de bouton... à moins de passer par une chaine dynamique, seul hic, tu perd les adresses et donc tu ne peux plus les liberer

    Pose des questions sur ce que tu ne comprend pas

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 16
    Points : 11
    Points
    11
    Par défaut
    Merci de ta réponse!

    Désolé de te répondre aussi tard mais j'ai eu des problèmes de connexion à Internet ce week-end... Bref, ton corrigé m'a été très utile... Reste toutefois le problème du nombre à afficher... Effectivement, comme tu l'as très bien expliqué, je ne peux passer par la variable i (j'obtiens toujours la même valeur)...

    Mais je ne vois toujours pas comment me servir du tableau de boutons... En effet, j'avais d'abord pensé à utiliser un gtk_button_get_label (GTK_BUTTON(pBouton)) à la place de &i, mais bien sûr, ca ne fonctionne pas...

    J'ai aussi essayé un atoi( &c[i]) (étant donné que l'on veut la valeur correspondant au bouton), mais ca ne fonctionne pas non plus...

    De plus, dans la fonction callback fenetreReponse, à quoi servent:

    g_printf ("%d\n", *n); (à la ligne 73)
    (void) wid; (à la ligne 105)

    ?

    Merci encore.

  4. #4
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Citation Envoyé par simtim
    Mais je ne vois toujours pas comment me servir du tableau de boutons... En effet, j'avais d'abord pensé à utiliser un gtk_button_get_label (GTK_BUTTON(pBouton)) à la place de &i, mais bien sûr, ca ne fonctionne pas...
    Le premier argument d'un callback étant le GtkButton qui a déclenché l'événement, tu peux directement récupérer le label par rapport à cet argument et de ce fait, tu n'as plus besoin de passer une valeur au dernier argument de g_signal_connect

    Citation Envoyé par simtim
    J'ai aussi essayé un atoi( &c[i]) (étant donné que l'on veut la valeur correspondant au bouton), mais ca ne fonctionne pas non plus...
    Il faut éviter d'utiliser ces fonctions (atoi, atol, etc...). Si tu prend la solution expliqué juste au dessus, tu peux transformer la chaîne du label du bouton courant en entier avec la fonction strtol !

    Citation Envoyé par simtim
    De plus, dans la fonction callback fenetreReponse, à quoi servent:

    g_printf ("%d\n", *n); (à la ligne 73)
    (void) wid; (à la ligne 105)
    Heu le g_printf pas de soucis, je testais simplement la valeur de l'argument, j'ai juste oublié de l'enlever et quant à la dernière ligne bin si tu règles bien ton compilateur, il rale à chaque fois que tu n'utilises pas une variable et surtout un argument, ceci permet donc de lui faire "utiliser" l'argument, donc pas de warning

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 16
    Points : 11
    Points
    11
    Par défaut
    Franck.H a écrit:
    Le premier argument d'un callback étant le GtkButton qui a déclenché l'événement, tu peux directement récupérer le label par rapport à cet argument et de ce fait, tu n'as plus besoin de passer une valeur au dernier argument de g_signal_connect
    Le problème est que lorsque je met NULL au dernier argument du g_signal_connect qui connecte les boutons à la fonction callback fenetreReponse, la fenêtre réponse qui affiche le numéro correspondant au bouton n'apparaît pas,lorsqu'on clique sur un bouton. Je suis donc obligé de préciser ce dernier argument...

    Franck.H a écrit:
    Il faut éviter d'utiliser ces fonctions (atoi, atol, etc...). Si tu prend la solution expliqué juste au dessus, tu peux transformer la chaîne du label du bouton courant en entier avec la fonction strtol !
    Que j'utilise atoi ou strtol, j'ai toujours le même problème, ca compile, mais à l'execution, la fenetre réponse ne s'affiche pas...

    Est-ce que tu aurais donc stp une solution pour quoi mettre dans ce fameux dernier argument de g_signal_connect qui pose tant de problèmes?..

  6. #6
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    La meilleure solution et celle à qui je pensais consistais simplement à créer un tableau d'entiers de la même taille que ton tableau de boutons:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    #include <stdlib.h>
    #include <stdio.h>
    #include <gtk/gtk.h>
    #include <glib/gprintf.h>
     
    #define N 6
     
    //Cette procédure affiche une fenêtre affichant le numéro du bouton correspondant
    void fenetreReponse (GtkWidget * wid, gpointer data);
     
    int main (int argc, char **argv) {
     
    /* Franck.H - Déclaration d'un tableau d'entiers de meme taille que le
                  tableau de boutons. */
        int tab_val[N];
     
        GtkWidget *pFenetre,
                  *pVBox,
                  *pBouton [N];
     
        gchar c[5];
     
        gtk_init (&argc, &argv);
     
        //Création et définition de la fenêtre globale
        pFenetre = gtk_window_new (GTK_WINDOW_TOPLEVEL);
        gtk_window_set_default_size (GTK_WINDOW(pFenetre), 180, 300);
        gtk_window_set_position (GTK_WINDOW(pFenetre), GTK_WIN_POS_CENTER);
        gtk_window_set_title (GTK_WINDOW(pFenetre), "Tableau de Valeurs");
     
        //Création de la table 7 lignes et 1 colonne
        pVBox = gtk_vbox_new (TRUE, 0);
     
        gint i;
        for (i=0; i<N; i++) {
            //Création de chaque bouton
            g_sprintf (c, "%d", i+1);
            pBouton[i] = gtk_button_new_with_label (c);
     
    /* Franck.H - Initialisation du tableau durant la boucle. */
            tab_val [i] = i + 1;
     
            //Insertion de chaque bouton dans la table
            gtk_box_pack_start (GTK_BOX (pVBox), pBouton[i], TRUE, TRUE, 0);
     
            //Connexion de chaque bouton au signal "clicked"
            g_signal_connect (
                G_OBJECT(pBouton[i]), "clicked",
                G_CALLBACK(fenetreReponse), &tab_val[i]);
        }
     
        //Insertion de le table dans la fenetre
        gtk_container_add (GTK_CONTAINER(pFenetre), pVBox);
     
        //Connexion de la fenêtre au signal "destroy"
        g_signal_connect (G_OBJECT(pFenetre), "destroy", G_CALLBACK(gtk_main_quit), NULL);
     
        //Affichage de la fenêtre globale et tout son contenu
        gtk_widget_show_all (pFenetre);
        gtk_main ();
     
        return EXIT_SUCCESS;
    }
     
    void fenetreReponse (GtkWidget * wid, gpointer data) {
     
         GtkWidget *pFenetre, *pLabel;
        gchar c[5];
     
         gint * n = data;
     
         pFenetre = gtk_dialog_new_with_buttons (
             "Fenetre de reponse...",
             NULL,
             GTK_DIALOG_MODAL,
             GTK_STOCK_OK, GTK_RESPONSE_OK,
             NULL
         );
     
         //Création du label et insertion dans la fenêtre
         g_sprintf (c, "%d", *n);
         pLabel = gtk_label_new (c);
         gtk_box_pack_start (
             GTK_BOX (GTK_DIALOG (pFenetre)->vbox), pLabel, TRUE, TRUE, 0
         );
         gtk_widget_show_all (GTK_DIALOG (pFenetre)->vbox);
     
     
         //Affichage de la fenêtre
         switch (gtk_dialog_run (GTK_DIALOG (pFenetre)))
         {
            case GTK_RESPONSE_OK:
            default:
             break;
         }
     
         gtk_widget_destroy (pFenetre);
         (void) wid;
    }
    Il est vrai que l'autre solution proposée est possible si on met tout en place correctement mais celle ci-dessus reste des plus simple

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 16
    Points : 11
    Points
    11
    Par défaut
    Merci encore!

    Ca compile et s'execute impec!! C'est vrai que créer un tableau de valeurs était beaucoup plus simple... Merci encore et à la prochaine!!

    simtim.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Centrer des gtk.Label dans une gtk.Table?
    Par remistan dans le forum GTK+ avec Python
    Réponses: 2
    Dernier message: 20/12/2010, 18h52
  2. [CR XI] Problème dans une état de d'une table
    Par nabilfaouzi dans le forum SAP Crystal Reports
    Réponses: 2
    Dernier message: 10/03/2009, 12h21
  3. Petit problème dans une fonction
    Par Jiyuu dans le forum wxPython
    Réponses: 6
    Dernier message: 08/07/2008, 22h49
  4. Petit Problème d'une balise ancrée dans une autre
    Par stansoad0108 dans le forum Langage
    Réponses: 2
    Dernier message: 13/05/2008, 10h23
  5. Réponses: 3
    Dernier message: 15/07/2005, 17h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo