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 dans une autre callback


Sujet :

GTK+ avec C & C++

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2011
    Messages : 38
    Par défaut Callback dans une autre callback
    Bonjour à tous.

    Ce que j'ai un peu de mal à appréhender dans GTK c'est les callback... le plus
    importants quoi. C'est assez simple si on se limite à appeler des callbacks
    depuis la fenêtre principale...


    Mais si je veux faire 2 choses complètement différentes (qui nécessitent deux
    callbacks complètement différentes) en une seule callback c'est difficile...


    Je m'explique : Je voudrais qu'à l'appui sur un bouton de mon interface mon
    programme appelle une callback déroule mon algorithme et dessine dans ma
    DrawingArea.

    Seulement la callback pour l'appui sur un bouton est de la forme :
    g_signal_connect(*, "clicked", *);
    Et la callback pour dessiner avec cairo dans ma drawingArea c'est :
    g_signal_connect(*, "draw", *);

    Mes question sont donc :
    - Comment faire pour donc quand je clique sur mon bouton je puisse dessiner dans ma drawingArea ?
    - Je pense que la solution c'est d'imbriquer une callback dans une autre mais dans ce cas comment faire pour récupérer tous les paramètres nécessaires à la deuxième callback dans la première callback ? (sans variable globale)
    - Y'a-t-il un moyen d'appeler dans une callback une callback définie dans la fenêtre principale (main.c) de sorte que celle-ci soit appelée avec les bon paramètres (puisque les paramètres sont définis dans la fenêtre principale) ?

    Bonne soirée
    Merci.

  2. #2
    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
    Bonjour,

    ce que tu dois faire, c'est comprendre l'aspect événementiel: la boucle principale GTK est une pompe à événements, sur le même modèle que la plupart des toolkits. En réponse à ces événements, GTK effectue des actions.

    Les événements qui surviennent vont dans une file d'attente. Le premier événement dans la file est traité, puis supprimé de la file, et ainsi de suite... Si tu connectes une callback à un signal, cela signifie que tu souhaites être notifié quand c'est le tour de cet événement d'être traité.

    La solution à ton problème n'est donc pas d'appeler directement une callback à partir d'une autre callback mais de rajouter le bon événement dans la file d'attente pour que ce dernier déclenche la callback qui t'intéresse.

    Ainsi, dans ta callback en réponse au signal GtkButton::clicked, tu n'as qu'à émettre le signal "draw" sur le bon widget, soit directement (avec les fonctions g_signal_emit*, mais ce n'est pas le cas usuel), soit indirectement en appelant une fonction qui ajoutera l'événement qui t'intéresse dans la file d'événements. Une fois le traitement de ta callback associée à GtkButton::cliked terminé, tu rends automatiquement la main à la pompe à événements, qui va traiter les événements restants, jusqu'à traiter l'événement qui t'intéresse: la réception du signal "draw" pour ton widget.

    Pour provoquer l'ajout de l'événement "draw" dans la file d'événements (on dit aussi: "émission du signal draw"), il te suffit d'appeler gtk_widget_queue_draw (pour redessiner le widget entier) ou gtk_widget_queue_draw_area (pour redessiner une zone particulière du widget: c'est plus rapide si seule une petit portion est modifiée). Une fois son tour arrivé dans la pompe à événements, la callback associée à "draw" sera appelée. Mais garde donc à l'esprit que contrairement aux fonctions qui s'appellent les unes les autres, les appels de callbacks ne sont en général pas imbriqués.

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2011
    Messages : 38
    Par défaut
    Merci à toi. J'avais essayé plein de chose.

    Notamment émêttre un signal avec g_signal_emit mais à chaque fois
    j'avais un Core Dump ou bien rien du tout qui changeait...
    J'ai essayé de mettre une callback dans une autre mais pareil rien
    ne fonctionnait...


    Merci pour ces éclairsissement sur la façon de penser les Callback.
    Je pense qu'il faudra un peu de temps pour que je comprends bien
    et que je m'adapte.

    Grâce à toi j'ai pu faire ce que je voulais. Merci encore

    J'ai cependant encore une dernière question :
    J'ai dû remplacer ma variable locale à ma fonction main, nommée
    area (la DrawingArea) par une variable globale pour pouvoir
    appeler ma callback qui dessine avec gtk_widget_queue_draw(area).
    N'y-a-t'il pas un autre moyen de passer ma drawingArea en variable
    à ma callback appelé en cliquant sur un bouton à part via le paramètre
    gpointer data de ma callback ?

  4. #4
    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
    Non, il n'y a que le paramètre data qui te permette de passer des données au signal, donc si tu as plusieurs paramètres à passer, tu dois les encapsuler dans une structure (c'est une limitation de la version C de GTK, les bindings python par exemple te permettent de passer le nombre d'arguments de ton choix). En général je définis dans le main une structure locale Gui qui contient des pointeurs vers les widgets que je vais manipuler durant l'exécution. Mais tu peux aussi y encapsuler les données de ton application.

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2011
    Messages : 38
    Par défaut
    Ok merci. J'ai également fait une structure pour certaines de mes callbacks.

    En tout cas vous m'avez bien aidé. Merci beaucoup

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

Discussions similaires

  1. appel du callback dans une autre fonction
    Par amine_wn dans le forum Interfaces Graphiques
    Réponses: 0
    Dernier message: 08/04/2015, 18h07
  2. appel d'un autre callback dans une fonction
    Par jponsoda dans le forum Interfaces Graphiques
    Réponses: 4
    Dernier message: 23/06/2010, 10h01
  3. Réponses: 5
    Dernier message: 07/08/2008, 18h53
  4. Ajout d'un callback dans une figure
    Par dazhoid dans le forum Interfaces Graphiques
    Réponses: 3
    Dernier message: 16/11/2006, 14h05
  5. Fonction callback dans une classe
    Par julian_ross dans le forum MFC
    Réponses: 8
    Dernier message: 02/03/2004, 11h42

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