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 :

Callback et pointeur sur structure


Sujet :

GTK+ avec C & C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 55
    Par défaut Callback et pointeur sur structure
    Bonjour a tous,

    J'ai actuellement un problème pour réaliser mon programme en GTK+.

    J'utilise un pointeur sur structure que je passe en paramètre de ma fonction callback. Mais une fois passe à cette fonction, je n'arrive pas a accéder aux données.

    Par exemple:

    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
     
    typedef struct     s_ex
    {
        char                *str;
    }                         t_ex;
     
    gboolean   callback(GtkWidget *pWidget, gpointer pData)
    {
        /*   afficher str sur mon ecran   */
    }
     
    void          fonction_diverses(t_ex *structure)
    {
       g_signal_connect(..., ...., ...., callback, structure);
    }
    Donc voilà, bien sur ce code est à titre d'exemple pour illustrer mon problème.

    J' espère donc que vous pourrez m'aider à trouver la solution.

    Bonne soirée!

  2. #2
    Membre confirmé Avatar de skip78
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 247
    Par défaut
    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
     
    typedef struct     s_ex
    {
        char                *str;
    }                         t_ex;
     
    gboolean   callback(GtkWidget *pWidget, gpointer pData)
    {
        /*   afficher str sur mon ecran   */
        t_ex structure = NULL;
        structure = (t_ex*)malloc(sizeof(t_ex));
        structure = pData;
        printf("str = %s\n", structure->str);
    }
     
    void          fonction_diverses(t_ex *structure)
    {
       g_signal_connect(..., ...., ...., callback, structure);
    }

  3. #3
    Membre Expert
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Par défaut
    Attention, c'est une erreur de faire un malloc comme tu le fais, tu écrases immédiatement la valeur renvoyée par ton malloc, donc tu leakes la mémoire que tu viens d'allouer. Donc il faut supprimer cette ligne

  4. #4
    Membre confirmé Avatar de skip78
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 247
    Par défaut
    Ah ? oki
    Moi qui pensais que c'était obligatoire, j'en met partout
    Je vais voir si ca permet une améliorations des perfs de suite ! ^^

  5. #5
    Membre Expert
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Par défaut
    Oula, tu m'inquiètes là... Faut pas tous les virer non plus.. Quand tu manipules un pointeur, soit il pointe déjà sur une zone de mémoire valide (structure/tableau déclarée sur la pile, mémoire allouée ailleurs, ...) auquel cas tu n'as pas besoin de malloc. Par contre, si ton pointeur ne pointe "nul part", tu dois allouer de la mémoire avant de pouvoir le déréférencer.

  6. #6
    Membre confirmé Avatar de skip78
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 247
    Par défaut
    Non non mais t'inquietes pas lol, je parlais bien entendu des callbacks du genre.
    Je sais pas pourquoi, mais j'étais persuadé qu'il fallait faire une allocation mémoire avant de faire structure = data;
    Bon ca change pas grand chose, en terme de performances, mais c'est vrai qu'en y réfléchissant, ces mallocs étaient tout à fait superflus

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 55
    Par défaut
    En effet y a pas besoin de mallocer.

    Sinon ca marche! Merci beaucoup.
    C'est vrai que ce proceder pour acceder aux espaces memoires est un peu special. Mais ca marche!

    Encore merci!

  8. #8
    Membre confirmé Avatar de skip78
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 247
    Par défaut
    A noter que j'avais oublié un * en cours de route.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    void callback(GtkWidget *pWidget, gpointer pData)
    {
        /*   afficher str sur mon ecran   */
        t_ex *structure = (t_ex*) pData;
        printf("str = %s\n", structure->str);
     
        /*  modifier un élément de la structure  */
        structure->num = 1;
    }

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 55
    Par défaut
    Oui en effet, pour l'étoile j'ai corrigé tout seul.

    Sinon, j'aimerais savoir une dernière chose si je peux me permettre.
    A partir de ce moment là, j'aimerais savoir si le bouton a été enfoncé. Je voudrais donc faire ça avec un flag dans ma structure, ou checker le retour du callback.
    (Je sais pas ce qui est possible, et le mieux...)

    Cependant je ne veux pas vérifier ce flag dans la fonction callback elle meme, mais ailleurs.
    Et je n'arrive pas à checker le retour du 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
     
    typedef struct     s_ex
    {
        int                  flag;
    }                         t_ex;
     
    gboolean             callback(GtkWidget *pWidget, gpointer pData)
    {
         t_ex               *structure;
     
        structure = pData;
        structure->flag++;
        return (TRUE);
    }
     
    void                      fonction_diverses(t_ex *structure)
    {
       g_signal_connect(..., ...., ...., callback, structure);
     
       /*
       ** ici ou dans une autre fonction on affiche flag.
       ** permettant ainsi de savoir si le bouton a bien été enfoncé ou pas.
       */
    }

    Donc voila, qu'est ce qui est le mieux? Et comment le faire?

    Merci d'avance!
    Bonne soirée.

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 55
    Par défaut
    Ah, il semblerait que le week-end de paques ait frappé!

  11. #11
    Membre Expert
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Par défaut
    Il faut modifier "structure" dans ton callback, et utiliser l'information présente dans cette même structure à l'autre endroit de ton programme où tuveux vérifier si ton bouton a été enfoncé ou non.

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 55
    Par défaut
    Citation Envoyé par teuf13 Voir le message
    Il faut modifier "structure" dans ton callback, et utiliser l'information présente dans cette même structure à l'autre endroit de ton programme où tuveux vérifier si ton bouton a été enfoncé ou non.
    En effet mais je n'arrive pas à le mettre en place.

    Si par exemple je fais:

    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
    typedef struct     s_ex
    {
        int                  flag;
    }                         t_ex;
     
    gboolean             callback(GtkWidget *pWidget, gpointer pData)
    {
         t_ex               *structure;
     
        structure = pData;
        structure->flag = 1;
        return (TRUE);
    }
     
    void                      fonction_diverses(t_ex *structure)
    {
        structure->flag = 0;
        g_signal_connect(..., ...., ...., callback, structure);
        if (structure->flag == 1)
             /*
             ** Alors je sais que le bouton a ete enfonce et peut faire autre chose.
             */
    }

    Bah ca foire. Car ma condition est verifiée avant même que ma fenêtre soit créée par exemple, ou si c'est une boucle bah ma fenêtre se lance pas etc...

    Donc je sais pas quoi faire! ^^

    L'idée c'est: Afficher une première fenêtre.
    On appuye sur un bouton et une fois ce bouton appuyé
    On change totalement la fenêre, en ayant besoin de la rafraichir.

    Mais j'arrive pas à le mettre en place. Donc si quelqu'un avait encore le courage de m'expliquer ce serait chouette!

    Merci!

  13. #13
    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
    Ca ne peux pas fonctionner comme ca. L'appel de la fonction g_signal_connect(); ne fait que mettre en place la connexion d'un évènement à une fonction callback. Elle n'est pas bloquante (heureusement d'ailleurs ). Ce qui fait que le code qui suit est exécuté tout de suite derrière.

    La programmation d'un environnement graphique est basé sur l'évènementiel. J'ai différentes fonctions qui sont appelées au gré des évènements. Tu cherches à outre-passer ce fonctionnement. Forcément ca coince .

    Voila un synoptique de principe pour ce que tu recherches à faire :
    • Crée ta première fenêtre avec ton fâmeux bouton dedans.
    • Affecte la fonction callback à ce bouton.
    • affiche le tout et lance la boucle gtk (gtk_main().
    • Dans la fonction callback tu modifies la fenêtre actuelle en supprimant, ajoutant, modifiant autant de widget que tu veux.
    • mets à jour l'affichage de la fenêtre une fois modifiée toujours dans le callback avec un gtk_widget_show_all();


    La structure pourrais contenir la déclaration de tous les widgets de la première fenêtre. Tu la transmets au callback grâce à la fonction g_signal_connect();. Mais ca tu le fais déjà. Ainsi dans le callback tu as accès à tous les pointeurs graphiques que tu veux modifier. Et cerise sur le gâteau, tu n'as aucune déclaration de variable en global avec ce système .

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 55
    Par défaut
    Bon. Maintenant que nous rentrons un peu plus dans les détails, je peux présenter mon problème en profondeur.

    Mon idée pour apprendre le Gtk, faire un ptit compte à rebours.
    Donc: 1 fenêtres: 1 zone de texte, 3 zones d'entrées (h/m/s) et 2 boutons (run/quit)

    Une fois qu'on clique sur: Run - on check si les paramètres sont bons (chiffres positifs, et on les stocke) autrement on ecrit un message d'erreur correspondant.

    Le problème (comme je l'ai évoqué avant) est que lorsque les paramètres sont valides, mon compte à rebours s'exécute en mémoire mais pas dans ma fenêtre. (du au fait que la fonction callback ne puisse pas renvoyer son 'TRUE')

    Donc je sais pas si ça peut vous aider, vous éclairer ou quoi que se soit. Mais c'était mon idée.

    Je sais pas si elle est réalisable, sinon, comment ?

    Bonne soirée!

  15. #15
    Membre Expert
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Par défaut
    Ce que tu veux faire "quand la fonction callback renvoie TRUE", tu peux le faire dans la fonction callback elle-même non ?

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 55
    Par défaut
    Bah il ne me semble pas car si je le fais, comme je l'ai dis je n'arrive pas à raffraichir ma fenêtre. En mémoire ça se fait bien mais pas dans ma fenêtre.

    Et je suppose justement que c'est dû au fait que je veuille rafraichir ma fenêtre, mais sans avoir renvoyer TRUE.

    Comme c'est un compte à rebours, je dois dire quel temps il reste.
    Et je sais pas si c'est la bonne méthode de justement tester la valeur des entrées de saisie puis ensuite renvoyer le signal correspondant. Car ça à l'air de bloquer!

  17. #17
    Membre Expert
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Par défaut
    Hrm, dans ton callback, il ne faut rien faire de bloquant, ie si tu affiches juste une valeur et que tu quittes ta fonction, ton interface devrait être correctement rafraichie.

  18. #18
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 55
    Par défaut
    Oui si je modifie un paramètre et que je quitte.
    Or entre temps je fais plein de calculs donc, forcément ca merde

    Je me demandais donc quel était le moyen, permettant de dire:
    -le bouton a été enfoncé donc on va pouvoir rafraichir la page jusqu' à la fin du compte à rebours.

    Une idée?!

  19. #19
    Membre Expert
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Par défaut
    Interface qui se rafraichit => on ne bloque pas dans un callback. Tu peux aussi regarder http://gtk.developpez.com/faq/?page=...BOUCLE_refresh même si j'aime pas trop cette méthode.

  20. #20
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 55
    Par défaut
    Désolé du retard.

    En effet j'imagine que c'est pas très propre. Et même avec cette boucle j'ai encore quelques problèmes (bouton quit qui se fait attendre etc...)

    Enfin bref, merci beaucoup de votre aide!

    Je vais parcourrir mes recherches, en espérant finir par trouver une solution!

    Bonne soirée!

Discussions similaires

  1. pointeur sur structures
    Par Seimaya dans le forum Débuter
    Réponses: 33
    Dernier message: 26/08/2007, 18h13
  2. Réponses: 6
    Dernier message: 07/07/2007, 18h12
  3. pointeur sur structure
    Par julien.63 dans le forum C
    Réponses: 7
    Dernier message: 04/06/2007, 17h50
  4. problème pointeur sur structure
    Par lejohn dans le forum C
    Réponses: 9
    Dernier message: 01/05/2007, 13h17
  5. Réponses: 2
    Dernier message: 21/03/2007, 10h55

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