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 :

Qui envoie le signal ? (GtkCheckButton)


Sujet :

GTK+ avec C & C++

  1. #1
    Membre confirmé
    Homme Profil pro
    chercheur
    Inscrit en
    Décembre 2012
    Messages
    195
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : chercheur

    Informations forums :
    Inscription : Décembre 2012
    Messages : 195
    Par défaut Qui envoie le signal ? (GtkCheckButton)
    Bonjour,

    Je code en GTK+2 est j'ai besoin d'utiliser à présent des GtkCheckButton. Je ne sais pas à l'avance combien de boutons je vais avoir besoin, je vais donc utiliser un tableau de pointeurs sur des widgets GtkCheckButton, dont j’allouerai la taille dynamiquement. Jusque là, pas trop de problème.

    En guise d'exercice (pour moi), j'ai développé le petit bout de code suivant, qui sert d'exemple de ce que je voudrais faire :

    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
    /* essai sur les check buttons */
     
    #include <stdlib.h>
    #include <gtk/gtk.h>
     
    int main(int argc,char **argv)
    {
        GtkWidget* pWindow;
        GtkWidget* pCheck[10];
     
        GtkWidget *pVBox; /* une box verticale */
        void OnToggle(GtkWidget *pWidget, gpointer pData); /* fonction call back activation ou desactivation boutton */
        int i;
        char tmp[30];
     
        gtk_init(&argc,&argv);
     
        pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_window_set_title(GTK_WINDOW(pWindow), "Check buttons");
        gtk_window_set_default_size(GTK_WINDOW(pWindow), 320, 200);
     
        /* création de la box verticale */
        pVBox = gtk_vbox_new(FALSE, 0);
        /* Creation des boutons check */
        for (i=0;i<10;i++)
        {
            (void)sprintf(tmp,"essai %2d",i+1);
            pCheck[i]=gtk_check_button_new_with_label(tmp);
            /* ajout  dans la boite verticale */
            gtk_box_pack_start(GTK_BOX(pVBox), pCheck[i], FALSE, TRUE, 0);
        }
     
        /* ajout de la GtkVBox à la fenetre */
        gtk_container_add(GTK_CONTAINER(pWindow), pVBox);
     
        /* Connexion des signaux */
        g_signal_connect(G_OBJECT(pWindow), "destroy", G_CALLBACK(gtk_main_quit), NULL);
        for (i=0;i<10;i++)
            g_signal_connect(G_OBJECT(pCheck[i]), "toggled", G_CALLBACK(OnToggle), NULL);
     
        /*affichage de la fenetre */
        gtk_widget_show_all(pWindow);
        gtk_main();
        return EXIT_SUCCESS;
    }
     
    void OnToggle(GtkWidget *pToggle, gpointer data)
    {
        gboolean bEtat;
        /* Récupération de l'état du bouton */
        bEtat = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(pToggle));
        if (bEtat)
            (void)printf("coche\n");
        else
         (  void)printf("decoche\n");
     
    }
    Ca marche plutôt bien, mais le problème est évidement que les signaux émis par tous les widgets GtkCheckButton sont tous interceptés par la même fonction callback, ce qui ne me convient pas. Je ne vais pas créer un tableau de fonctions callback correspondant. Je voudrais donc trouver comment identifier le widget qui a émis le signal intercepté, mais je n'ai aucune idée de comment faire ceci.

    Notamment (et c'est un problème récurant dans ma compréhension de GTK), je ne comprends pas comment utiliser le dernier argument de la fonction callback (gpointer). Y aurait-il dans cet argument l'information recherchée et dont j'ai besoin, et si oui comment la récupérer ?

    Merci pour toute aide sur ce point.

    Eric.

  2. #2
    Membre confirmé Avatar de Gamall
    Profil pro
    Étudiant ENSEA
    Inscrit en
    Août 2009
    Messages
    252
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant ENSEA

    Informations forums :
    Inscription : Août 2009
    Messages : 252
    Par défaut
    Tu passes ton tableau en paramètre à ta callback :

    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
     
     
    g_signal_connect(G_OBJECT(pCheck[i]), "toggled", G_CALLBACK(OnToggle), pCheck);
     
    /* ... */
     
    void OnToggle(GtkCheckButton *btn, gpointer data)
    {
        long long int index = btn - GTK_CHECK_BUTTON(data);
     
        g_return_if_fail(index > 0);
        g_return_if_fail(index < 9);
     
        switch(index)
        {
            case 0:
            /* ... */
            break;
     
            /* ... */
     
            case 9:
            /* ... */
            break;
        }
    }

  3. #3
    Membre éclairé
    Profil pro
    Retraité
    Inscrit en
    Novembre 2009
    Messages
    331
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2009
    Messages : 331
    Par défaut
    Il me semble que c'est plutôt:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    g_signal_connect(G_OBJECT(pCheck[i]), "toggled", G_CALLBACK(OnToggle) ,GINT_TO_POINTER(i));
    puisque c'est le numéro du bouton qu'il faut passer
    et donc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    void OnToggle(GtkCheckButton *btn, gpointer p)
    {
        gint index = GPOINTER_TO_INT(p);

  4. #4
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 308
    Billets dans le blog
    5
    Par défaut
    J'apporte une petite variante aux réponses données.

    Effectivement tous les boutons exécutent la même fonction. Cependant, tu récupères dans la dite fonction le pointeur du bouton appuyé (le premier argument). Tu peux simplement contrôler le nom du label du bouton transmis pour savoir lequel est activé.

    Remarque : transmettre pCheck[i] ne sert finalement à rien puisque le pointeur est déjà transmis au callback.

    On économise le user data par cette méthode pour une autre utilisation.

    Finalement, tous les chemins mènent à Rôme .

  5. #5
    Membre confirmé
    Homme Profil pro
    chercheur
    Inscrit en
    Décembre 2012
    Messages
    195
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : chercheur

    Informations forums :
    Inscription : Décembre 2012
    Messages : 195
    Par défaut
    La solution de pvincent marche très bien, et est claire. Merci !

    Pour gerald3d: Ok, merci. Mais je ne sais simplement pas comment récupérer le label du bouton transmis pour savoir lequel est activé dans la fonction callback. par ailleurs, je peux avoir des checkbuttons sans label, etc. Un exemple serait utile, au besoin.

    En tout cas merci pour vos explications et exemples. Je passe le post en "résolu".

    Eric.

  6. #6
    Membre éprouvé
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Par défaut
    Personnellement je code en GTK+3

    Mais d'abords le gpointer peut prendre n'importe quelle type, c'est le principe du pointeur générique,

    Ca veut dire que tu peut écrire ta fonction de callback comme ceçi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void get_toggle_button(GtkWidget widget, int *my_param) {
     
      fprintf(stdout,"Widget N° %d\n", (*my_param) ) ;
     
      return ;
     
    }
    Sinon la paire de fonction:

    gtk_widget_set_name(...) et

    gtk_widget_get_name(...)

    est pratique pour identifier un widget précis.


    Bon gtk a toi.

  7. #7
    Membre confirmé
    Homme Profil pro
    chercheur
    Inscrit en
    Décembre 2012
    Messages
    195
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : chercheur

    Informations forums :
    Inscription : Décembre 2012
    Messages : 195
    Par défaut
    Citation Envoyé par Luke spywoker Voir le message
    Sinon la paire de fonction:

    gtk_widget_set_name(...) et

    gtk_widget_get_name(...)
    est pratique pour identifier un widget précis.
    Effectivement, très (très!) pratique. Je viens de faire des essais, et je crois que ces deux fonctions vont m'être très utiles !

    Merci!

    Eric.

  8. #8
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Par défaut
    Perso j'utilise la même solution que pvincent. Si j'ai besoin de passer plus d'informations dans le user data, je passe une structure avec un membre contenant l'indice, les modifications sont minimes.

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

Discussions similaires

  1. Comment insérer un lien qui envoie sur outlook ?
    Par CamilleLh dans le forum Balisage (X)HTML et validation W3C
    Réponses: 1
    Dernier message: 02/01/2007, 18h44
  2. Réponses: 1
    Dernier message: 26/11/2006, 10h57
  3. Réponses: 2
    Dernier message: 03/05/2006, 00h12
  4. envoi de signal selon un timing très précis
    Par shura dans le forum POSIX
    Réponses: 3
    Dernier message: 17/12/2004, 16h32

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