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 :

affichage dynamique d'une trajectoire


Sujet :

GTK+ avec C & C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 25
    Par défaut affichage dynamique d'une trajectoire
    Bonjour,

    J'essaie de mettre au point l'affichage dynamique d'une trajectoire. Je m'explique : j'affiche tout d'abord une carte (au sens géographique: il s'agit de la répartition d'une ressource alimentaire pour un animal). Jusque là tout va bien.
    Mais ensuite, je voudrait afficher la trajectoire de l'animal sur cette carte, mais de façon dynamique de telle manière que l'on voie l'animal se déplacer clairement sur la carte. J'ai tenté d'utiliser un code (ici le tracé est stupide ) qui ressemble à ceci :

    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
     
        gtk_widget_show (pDrawable); // affichage de la carte
        gtk_widget_show (window);
     
        gtk_grab_add(pDrawable);
        gdk_gc_set_foreground (gc, &couleur[25]);
        for (i=0; i< 5; i++)
        {
        gdk_draw_line(pixmap, gc, 100+10*i, 100+5*i, 100 + 10*i, 100 + 15*i);
        gtk_main_iteration ();
        sleep(1000);
        }
        gtk_grab_remove(pDrawable);
     
        return(0);
    }
    Ce que j'obtiens, c'est l'affichage de l'intégralité (carte + lignes) en une seule fois et non pas la carte puis séquentiellement les 5 traits avec un intervalle d'une seconde.

    Quelqu'un a une idée ? Ca m'aiderait vraiment beaucoup !
    Merci d'avance,

    Cordialement à tous, P.

  2. #2
    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
    sleep(1000); => beurk!!!

    L'utilisation d'une boucle d'attente va figer ton interface. Il faut que tu insères l'affichage dans une fonction qui sera appelée à intervalle régulier par la boucle principale de Gtk+. Pour ca tu as la fonction g_timeout_add(); et ses dérivées.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 25
    Par défaut
    Citation Envoyé par gerald3d Voir le message
    sleep(1000); => beurk!!!

    L'utilisation d'une boucle d'attente va figer ton interface. Il faut que tu insères l'affichage dans une fonction qui sera appelée à intervalle régulier par la boucle principale de Gtk+. Pour ca tu as la fonction g_timeout_add(); et ses dérivées.

    Merci beaucoup ! j'essaie ça tout de suite... (pour le sleep, tu as raison: beurk).

    cordialement, P.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 25
    Par défaut
    Citation Envoyé par gerald3d Voir le message
    sleep(1000); => beurk!!!

    L'utilisation d'une boucle d'attente va figer ton interface. Il faut que tu insères l'affichage dans une fonction qui sera appelée à intervalle régulier par la boucle principale de Gtk+. Pour ca tu as la fonction g_timeout_add(); et ses dérivées.
    Bon, je viens d'essayer g_timeout_add suivant ton conseil. Mais c'est curieux, il faut que je provoque un rafraichissement de la fenêtre pour voir ma trajectoire avancer un peu... Bref pour me tracer 414 coordonnées, il faut que je rafraichisse 5 ou 6 fois. En fait, le résultat est très proche de ce que j'avais avec ma boucle d'attente, mais c'est quand même un peu mieux !

    Voilà. Désolé de te solliciter encore mais si vois d'où vient le blocage, je suis très preneur. Merci d'avance, P.

    Voici ce 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
    /*-------------------------------------------------------------*/
    /* en cas d'agrandissement / deplacement de la fen. graphique   */
    /*------------------------------------------------------------*/
    
    static gboolean rafraichissement( GtkWidget *pDrawable, GdkEventExpose *event )
    {
            gdk_draw_drawable( pDrawable->window,                       pDrawable->style->fg_gc[GTK_WIDGET_STATE(pDrawable)],
                               pixmap, event->area.x, event->area.y, event->area.x,
                               event->area.y, -1, -1 );
            return FALSE;
    }
    /*-------------------------------------------------------------*/
    /* la trajectoire : tracer                                                        */
    /*------------------------------------------------------------*/
    
    static gboolean trace_trajectoire(GtkWidget *pDrawable)
    {
    int i;
       gtk_grab_add(pDrawable);
       for (i=0; i< 413; i++)
           {
            gdk_draw_line(pixmap, gc, 8*Matrice_t[i][0], 8*Matrice_t[i][1], 8*Matrice_t[i+1][0],8* Matrice_t[i+1][1]);
            gtk_main_iteration ();
        }
       gtk_grab_remove(pDrawable);
    
       return (FALSE);
    }
    
    /*-------------------------------------------------------------*/
    /* appel de trace_trajectoire() dans une fonction elle même invoquée par
        g_signal_connect(G_OBJECT(pButton2), "clicked",
                         G_CALLBACK(FenetreGraphique), NULL);             
    /*------------------------------------------------------------*/
    
    
    /....
    
        gtk_widget_show (pDrawable);
        gtk_widget_show (window);
        charge_trajectoire();               // charger la Matrice_t de la trajectoire
    
        gdk_gc_set_foreground (gc, &couleur[25]);  // couleur rouge fonce pour la trajectoire
        data = pDrawable;
        g_timeout_add(100,trace_trajectoire, data) ; // appels a intervalles reguliers
        return(0);
    }

  5. #5
    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
    Pour commencer tu donnes la valeur 100. N'oublies pas que c'est en milliseconde. Essayes déjà avec un laps de temps plus long. Ensuite ajouter un dessin à un GtkDrawingArea demande de repasser par le signal "expose-event". Ou du moins solliciter un rafraîchissement d'une partie du graphique.

    Une dernière remarque qui n'a rien à voir avec le problème. Utilises les balises CODE/CODE (le petit # dnas la barre d'outils d'édition des messages pour mettre en forme le code que tu nous donnes. C'est plus facile à lire.

  6. #6
    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
    Tu peux aussi jeter un coup d'oeil sur l'exemple d'animation de pixbufs dans gtk-demo.

  7. #7
    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
    Je préconise néanmoins l'utilisation de g_idle_add. Dans la callback associée, tu calculeras la position de tes objets à dessiner d'après le temps écoulé (tu peux utiliser un GTime).

    Utiliser un g_timeout_add est en général une mauvaise idée pour de l'animation, car ils n'ont pas de précision garantie. Ce n'est une bonne idée que si tu ne calcules pas la position de ton objet en fonction d'un incrément fixe (par exemple la nième image sur une série), mais en fonction du temps écoulé depuis le début de l'animation (ce qui te permettra d'éviter des effets d'accélération/ralentissement dûs à des imprécisions).

    Pour améliorer les performances, n'invalide que la zone minimum à redessiner (avec gdk_window_invalidate_rect ou gdk_window_invalidate_region je crois). Tu peux aussi utiliser cairo plutôt que gdk (ce que je te recommande chaudement, tu ne pourras utiliser que cairo dans GTK3 et plus les fonctions de dessin gdk).

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 25
    Par défaut
    Citation Envoyé par liberforce Voir le message
    Je préconise néanmoins l'utilisation de g_idle_add. Dans la callback associée, tu calculeras la position de tes objets à dessiner d'après le temps écoulé (tu peux utiliser un GTime).

    Utiliser un g_timeout_add est en général une mauvaise idée pour de l'animation, car ils n'ont pas de précision garantie. Ce n'est une bonne idée que si tu ne calcules pas la position de ton objet en fonction d'un incrément fixe (par exemple la nième image sur une série), mais en fonction du temps écoulé depuis le début de l'animation (ce qui te permettra d'éviter des effets d'accélération/ralentissement dûs à des imprécisions).

    Pour améliorer les performances, n'invalide que la zone minimum à redessiner (avec gdk_window_invalidate_rect ou gdk_window_invalidate_region je crois). Tu peux aussi utiliser cairo plutôt que gdk (ce que je te recommande chaudement, tu ne pourras utiliser que cairo dans GTK3 et plus les fonctions de dessin gdk).
    Bon, merci à Gerald et Liberforce pour vos conseil. Le truc n'est pas totalement abouti mais ça avance (suis un peu débordé en ce moment) ...lentement. En tout cas j'ai appris des choses. Dès que j'ai une solution satisfaisante, je mettrais un petit bout de code en ligne.
    En tout cas merci !

Discussions similaires

  1. Affichage dynamique d'une trajectoire
    Par Texanito dans le forum Programmation multimédia/Jeux
    Réponses: 4
    Dernier message: 09/12/2010, 18h29
  2. Réponses: 2
    Dernier message: 29/11/2006, 15h42
  3. Affichage dynamique d'une valeur calculée
    Par harley dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 06/06/2006, 09h20
  4. [Tableaux] Ajouter l'affichage dynamique d'une image
    Par leloup84 dans le forum Langage
    Réponses: 3
    Dernier message: 16/02/2006, 09h14
  5. Problème d'affichage dynamique d'une liste
    Par bor1s dans le forum ASP
    Réponses: 2
    Dernier message: 18/11/2005, 16h18

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