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 :

Comportement de fenêtres GTK+ avec dessins


Sujet :

GTK+ avec C & C++

  1. #21
    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
    Points : 2 002
    Points
    2 002
    Par défaut
    Le configure-event est émis quand la fenêtre change de taille, car cela peut modifier la façon de dessiner dans la fenêtre. En général on sauvegarde les paramètres dépendants de la taille de la fenêtre, et on les prend ensuite en compte dans l'expose-event. Mais il y a un soucis, j'ai déjà fait des applis dessinant dans du GtkDrawingArea, et le comportement que vous m'annoncez me parait pas normal du tout, et contredit d'ailleurs la doc...

  2. #22
    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
    Points : 2 002
    Points
    2 002
    Par défaut
    Au passage, tentez de changer la valeur de retour de la callback du expose-event de FALSE à TRUE... J'ai un gros relent d'intuition masculine

    Ce que semble confirmer l'exemple GtkDrawingArea de gtk-demo...

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

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

    Informations forums :
    Inscription : Février 2008
    Messages : 2 302
    Points : 4 965
    Points
    4 965
    Billets dans le blog
    5
    Par défaut
    Je suis d'accord avec toi. D'autant que ca fait maintenant un moment que j'utilise ce widget et je n'ai jamais rencontré de problème pour ce qui est du rafraîchissement.
    Maintenant est-ce que le gestionnaire de fenêtre n'en prendrait pas une part pour lui? Tant que la fenêtre ne change pas de taille il n'y a pas de raison de calculer, donc l'image tampon affichée peut être utilisée. Tout ceci n'est qu'une supposition de ma part, il va de soit.

  4. #24
    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
    Points : 2 002
    Points
    2 002
    Par défaut
    Il y a eu collision de posts je crois . Regarde mon message juste au dessus...

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

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

    Informations forums :
    Inscription : Février 2008
    Messages : 2 302
    Points : 4 965
    Points
    4 965
    Billets dans le blog
    5
    Par défaut
    Effectivement il y a un relent. Mais ca sent pas très bon . Non ca ne change rien.

    J'ai continué dans ma recherche. Je me suis dit "tiens puisqu'il n'y a rien de dessiner dedans peut être que c'est normal".
    J'ai donc ajouté une image dans mon GtkDrawingArea. Elle est parfaitement rafraîchie lorsqu'une autre fenêtre viens dessus. Et le tout sans aucun signal "expose-event" d'émit .

    Je le sens de plus en plus le coup du gestionnaire de fenêtre qui met son grain de sel la dedans...

  6. #26
    Membre confirmé
    Profil pro
    Retraité
    Inscrit en
    Novembre 2009
    Messages
    330
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2009
    Messages : 330
    Points : 607
    Points
    607
    Par défaut
    @ Slooker,
    Je voudrai faire part de mon expérience.
    Il y a plus de 20 ans, j'ai développé un programme mélangeant Fortran et C. Lassé par les ajustements à faire à chaque changement de compilateur ou de système d'exploitation (dans la douleur car je suis physicien et non informaticien), j'ai alors changé de méthode: depuis mes programmes Fortran écrivent des fichiers de commandes pour les logiciels de dessin adéquats (j'utilise Scilab pour les cartes de champ et Grace (maintenant GraceGTK) pour les courbes, mais il en existe bien d'autres), puis CALL SYSTEM () pour lancer le dessin... Il existe d'ailleurs une bibliothèque Fortran pour l'interfacage avec Grace. Ceci permet de remplir une très grande partie de mes besoins et autorise un post-traitement aisé des résultats.
    Si on accepte le mélange Fortran/C, on peut aussi (je ne l'ai jamais fait) utiliser les widgets spécialisés de gtk+extra (gtkplot,...)
    Bien sûr, je ne sais pas si dans ton cas la programmation directe n'est pas la meilleure solution, mais je voulais rappeler qu'il existe d'autres possibilités.

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

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

    Informations forums :
    Inscription : Février 2008
    Messages : 2 302
    Points : 4 965
    Points
    4 965
    Billets dans le blog
    5
    Par défaut
    Oui pvincent tu as raison. Il existe plusieurs manières d'arriver à ses fins.
    Ce post à légèrement dérivé, même si nous sommes toujours dans le sujet. Nous ne trouvons pas comment Gtk+ rafraîchit ses fenêtres autre que par l'appel du signal "expose-event". Et dans les faits ce signal est très peut sollicité. D'où notre discussion .

  8. #28
    Membre actif 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
    Points : 221
    Points
    221
    Par défaut
    Citation Envoyé par gerald3d Voir le message
    Effectivement il y a un relent. Mais ca sent pas très bon . Non ca ne change rien.

    J'ai continué dans ma recherche. Je me suis dit "tiens puisqu'il n'y a rien de dessiner dedans peut être que c'est normal".
    J'ai donc ajouté une image dans mon GtkDrawingArea. Elle est parfaitement rafraîchie lorsqu'une autre fenêtre viens dessus. Et le tout sans aucun signal "expose-event" d'émit .

    Je le sens de plus en plus le coup du gestionnaire de fenêtre qui met son grain de sel la dedans...
    Oui, a mon avis aussi, ça se passe plutôt du côté de metacity ou compiz, par contre, faudrait voir ce que ça donne sous Kde

  9. #29
    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
    Points : 2 002
    Points
    2 002
    Par défaut
    Non, franchement, je ne crois pas à la piste du gestionnaire de fenêtres...
    Pour le coup des évènements, tu auras peut être une différence de comportement côté évènements entre GtkWindow et GtkDrawingArea, à cause du double buffering ou du flag GTK_APP_PAINTABLE:

    Generally, applications use the pre-defined widgets in GTK+ and they do not draw extra things on top of them (the exception being GtkDrawingArea). However, applications may sometimes find it convenient to draw directly on certain widgets like toplevel windows or event boxes. When this is the case, GTK+ needs to be told not to overwrite your drawing afterwards, when the window gets to drawing its default contents.

    GtkWindow and GtkEventBox are the only two widgets which will draw their default contents unless you turn on the GTK_APP_PAINTABLE widget flag. If you turn on this flag, then they will not draw their contents and let you do it instead.
    Source: The GTK+ Drawing Model

    Donc qu'on voie moins d'expose-event pour GtkWindow ne me choque pas, vu qu'il n'y a que GtkDrawingArea qui par défaut puisse être redessiné par l'application. L'expose-event n'est peut être pas envoyé quand le double buffering permet de faire le boulot de manière transparente...

    Gerald, tu peux modifier ton exemple pour lister les évènements d'un GtkDrawingArea plutôt que ceux d'un GtkWindow ?

  10. #30
    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
    Points : 2 002
    Points
    2 002
    Par défaut
    Citation Envoyé par gerald3d Voir le message
    Je n'ai jamais rencontré ce genre de problème. Maintenant je n'ai jamais dessiné directement dans un GtkWindow. Mes dessins se sont toujours faits dans un GtkDrawingArea. Est-ce que ca fait une différence? Pas sûr...
    Je comprends mieux ta remarque. La manière de dessiner via cairo ne change pas, mais GtkWindow dessine automatiquement son contenu par défaut, et pas GtkDrawingArea...

  11. #31
    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
    Points : 2 002
    Points
    2 002
    Par défaut
    Bon, je n'avais pas vu qu'il dessinait directement dans la GtkWindow. La solution est donc sans doute de dessiner dans une GtkDrawingArea insérée dans la GtkWindow (solution la plus propre), ou bien appeler gtk_widget_set_app_paintable sur la GtkWindow.

  12. #32
    Membre actif 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
    Points : 221
    Points
    221
    Par défaut
    Citation Envoyé par liberforce Voir le message
    Non, franchement, je ne crois pas à la piste du gestionnaire de fenêtres...
    Pour le coup des évènements, tu auras peut être une différence de comportement côté évènements entre GtkWindow et GtkDrawingArea, à cause du double buffering ou du flag GTK_APP_PAINTABLE:


    Source: The GTK+ Drawing Model

    Donc qu'on voie moins d'expose-event pour GtkWindow ne me choque pas, vu qu'il n'y a que GtkDrawingArea qui par défaut puisse être redessiné par l'application. L'expose-event n'est peut être pas envoyé quand le double buffering permet de faire le boulot de manière transparente...

    Gerald, tu peux modifier ton exemple pour lister les évènements d'un GtkDrawingArea plutôt que ceux d'un GtkWindow ?
    Je sais pas si t'as regardé le code que j'ai posté, mais j'utilisais une GtkDrawingArea, et d'ailleurs, je dessine jamais dans autre chose qu'une GtkDrawingArea.

    Bon, pendant que j'y suis je poste le code de gerald avec une GtkDrawingArea:
    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
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    #include <gtk/gtk.h>
     
    gboolean event_emitted (GtkWidget *widget, GdkEvent  *event, gpointer user_data)
    {
      g_print("event emitted : ");
     
      switch (event->type)
      {
        case GDK_NOTHING:
          g_print("GDK_NOTHING\n");
          break;
        case GDK_DELETE:
          g_print("GDK_DELETE\n");
          break;
        case GDK_DESTROY:
          g_print("GDK_DESTROY\n");
          break;
        case GDK_EXPOSE:
          g_print("GDK_EXPOSE\n");
          break;
        case GDK_MOTION_NOTIFY:
          g_print("GDK_MOTION_NOTIFY\n");
          break;
        case GDK_BUTTON_PRESS:
          g_print("GDK_BUTTON_PRESS\n");
          break;
        case GDK_2BUTTON_PRESS:
          g_print("GDK_2BUTTON_PRESS\n");
          break;
        case GDK_3BUTTON_PRESS:
          g_print("GDK_3BUTTON_PRESS\n");
          break;
        case GDK_BUTTON_RELEASE:
          g_print("GDK_BUTTON_RELEASE\n");
          break;
        case GDK_KEY_PRESS:
          g_print("GDK_KEY_PRESS\n");
          break;
        case GDK_KEY_RELEASE:
          g_print("GDK_KEY_RELEASE\n");
          break;
        case GDK_ENTER_NOTIFY:
          g_print("GDK_ENTER_NOTIFY\n");
          break;
        case GDK_LEAVE_NOTIFY:
          g_print("GDK_LEAVE_NOTIFY\n");
          break;
        case GDK_FOCUS_CHANGE:
          g_print("GDK_FOCUS_CHANGE\n");
          break;
        case GDK_CONFIGURE:
          g_print("GDK_CONFIGURE\n");
          break;
        case GDK_MAP:
          g_print("GDK_MAP\n");
          break;
        case GDK_UNMAP:
          g_print("GDK_UNMAP\n");
          break;
        case GDK_PROPERTY_NOTIFY:
          g_print("GDK_PROPERTY_NOTIFY\n");
          break;
        case GDK_SELECTION_CLEAR:
          g_print("GDK_SELECTION_CLEAR\n");
          break;
        case GDK_SELECTION_REQUEST:
          g_print("GDK_SELECTION_REQUEST\n");
          break;
        case GDK_SELECTION_NOTIFY:
          g_print("GDK_SELECTION_NOTIFY\n");
          break;
        case GDK_PROXIMITY_IN:
          g_print("GDK_PROXIMITY_IN\n");
          break;
        case GDK_PROXIMITY_OUT:
          g_print("GDK_PROXIMITY_OUT\n");
          break;
        case GDK_DRAG_ENTER:
          g_print("GDK_DRAG_ENTER\n");
          break;
        case GDK_DRAG_LEAVE:
          g_print("GDK_DRAG_LEAVE\n");
          break;
        case GDK_DRAG_MOTION:
          g_print("GDK_DRAG_MOTION\n");
          break;
        case GDK_DRAG_STATUS:
          g_print("GDK_DRAG_STATUS\n");
          break;
        case GDK_DROP_START:
          g_print("GDK_DROP_START\n");
          break;
        case GDK_DROP_FINISHED:
          g_print("GDK_DROP_FINISHED\n");
          break;
        case GDK_CLIENT_EVENT:
          g_print("GDK_CLIENT_EVENT\n");
          break;
        case GDK_VISIBILITY_NOTIFY:
          g_print("GDK_VISIBILITY_NOTIFY\n");
          break;
        case GDK_NO_EXPOSE:
          g_print("GDK_NO_EXPOSE\n");
          break;
        case GDK_SCROLL:
          g_print("GDK_SCROLL\n");
          break;
        case GDK_WINDOW_STATE:
          g_print("GDK_WINDOW_STATE\n");
          break;
        case GDK_SETTING:
          g_print("GDK_SETTING\n");
          break;
        case GDK_OWNER_CHANGE:
          g_print("GDK_OWNER_CHANGE\n");
          break;
        case GDK_GRAB_BROKEN:
          g_print("GDK_GRAB_BROKEN\n");
          break;
        case GDK_DAMAGE:
          g_print("GDK_DAMAGE\n");
          break;
      }
     
      return FALSE;
    }
     
    int
    main(int argc, char ** argv)
    {
    	GtkWidget *window;
    	GtkWidget *draw;
     
    	gtk_init (&argc, &argv);
     
    	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    	gtk_window_set_default_size (GTK_WINDOW(window), 320, 200);
    	g_signal_connect (G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
     
    	draw = gtk_drawing_area_new ();
    	gtk_widget_set_events (draw, GDK_ALL_EVENTS_MASK);
    	g_signal_connect (G_OBJECT(draw), "event", G_CALLBACK(event_emitted), NULL);
    	gtk_container_add (GTK_CONTAINER(window), draw);
     
    	gtk_widget_show_all (window);
     
    	gtk_main ();
     
    	return 0; 
    }
    Bref, toujours pareil, l'expose event n'est émis que lorsque la fenêtre est réduite dans la barre des tâches.

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

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

    Informations forums :
    Inscription : Février 2008
    Messages : 2 302
    Points : 4 965
    Points
    4 965
    Billets dans le blog
    5
    Par défaut
    Tout à fait d'accord avec toi. Que ce soit avec un GtkDrawingArea ou un GtkWindow le comportement est exactement le même. Donc j'insiste, le gestionnaire de fenêtre ne doit pas être étranger à tout ceci.

  14. #34
    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
    Points : 2 002
    Points
    2 002
    Par défaut
    Citation Envoyé par Slookeur Voir le message
    je développe un programme Fortran90/C/Gtk+, à une certaine étape je dessine des courbes dans une GtkWindow en utilisant Cairo:
    Citation Envoyé par gerald3d Voir le message
    Voila un petit code qui affiche les évènements emits par un GtkWindow. Le code n'est pas propre mais au moins ca donne une idée de la chose.
    D'où ma confusion. Bon, je vais arrêter les supputations tant que je n'ai pas l'occasion de compiler et tester par moi même...

  15. #35
    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
    Points : 2 002
    Points
    2 002
    Par défaut
    Bon, je viens de tester, et j'ai un comportement normal, c'est à dire que l'expose-event (GDK_EXPOSE) est transmis dès que la zone à afficher change. Par exemple quand une partie cachée par une autre fenêtre est découverte. Ou qu'on passe une autre application maximisée à l'avant plan, et qu'on repasse l'application de test à l'avant plan...

    Configuration: Mandriva Linux 2010.1, GNOME 2.30, GTK 2.20, gestionnaire de fenêtres: Metacity.

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

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

    Informations forums :
    Inscription : Février 2008
    Messages : 2 302
    Points : 4 965
    Points
    4 965
    Billets dans le blog
    5
    Par défaut
    Même configuration hormis que compiz s'occupe de la gestion fenêtrée. Ceci explique peut être cela...

  17. #37
    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
    Points : 2 002
    Points
    2 002
    Par défaut
    J'ai testé avec la même configuration mais en utilisant compiz à la place de metacity comme gestionnaire de fenêtre. Effectivement, il y a moins d'expose-event envoyés. Celui ci n'est en fait appelé que lorsque c'est nécessaire, à savoir quand le contenu à afficher va changer. C'est peut être à cause du compositeur, qui retraite les images avant de les afficher, ou peut être depuis la gestion de l'offscreen rendering... Je ne sais pas trop. Toujours est il que cela fonctionne comme du double buffering, Vu qu'on a déjà l'image de ce qu'il y a à afficher, si la fenêtre est recouverte par une autre puis découverte, pas besoin de tout redessiner, et donc pas besoin d'envoyer un expose-event: on réutilise juste ce qui a déjà été dessiné. C'est une différence de fonctionnement, mais le résultat est identique.

    Citation Envoyé par Slookeur Voir le message
    La courbe est tracée pas de soucis seulement quand je masque la fenêtre dans la barre des taches et que je la fait réapparaître son contenu a été effacé ...
    J'ai un exemple de code cairo que j'avais déjà posté ici (cairo-plot), et il fonctionne très bien, il n'y a pas ton bug... Et c'est juste une GtkDrawingArea dans laquelle je dessine...

    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 <gtk/gtk.h>
    #include <math.h>
    #include <cairo.h>
     
    #define WIDTH   640
    #define HEIGHT  480
     
    #define ZOOM_X  100.0
    #define ZOOM_Y  100.0
     
     
    gfloat f (gfloat x)
    {
    	return 0.03 * pow (x, 3);
    }
     
    static gboolean
    on_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
    {
    	cairo_t *cr = gdk_cairo_create (widget->window);
    	GdkRectangle da;            /* Dimensions de la GtkDrawingArea */
    	gdouble dx = 5.0, dy = 5.0; /* Nombre de pixels entre chaque point calculé */
    	gdouble i, clip_x1 = 0.0, clip_y1 = 0.0, clip_x2 = 0.0, clip_y2 = 0.0;
    	gint unused = 0;
     
    	/* On définit la zone de clipping, cela correspond à la zone à 
    	 * raffraîchir. En ne dessinant que le strict nécessaire, on dessinera 
    	 * plus rapidement */
    	cairo_rectangle (cr, 
    			event->area.x, 
    			event->area.y, 
    			event->area.width, 
    			event->area.height);
    	cairo_clip (cr);
     
    	/* On détermine les dimensions de la GtkDrawingArea */
    	gdk_window_get_geometry (widget->window, 
    			&da.x, 
    			&da.y, 
    			&da.width, 
    			&da.height, 
    			&unused);
     
    	/* On dessine un fond noir */
    	cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
    	cairo_paint (cr);
     
    	/* On change la matrice de transformation. C'est comme un changement 
    	 * de repère en mathématiques. On centre d'abord l'origine du repère.
    	 * Ensuite on change son échelle */
    	cairo_translate (cr, da.width / 2, da.height / 2);
    	cairo_scale (cr, ZOOM_X, -ZOOM_Y);  
     
    	/* On détermine les points à calculer (c'est à dire ceux se trouvant 
    	 * dans la zone de clipping) */
    	cairo_device_to_user_distance (cr, &dx, &dy);
    	cairo_clip_extents (cr, &clip_x1, &clip_y1, &clip_x2, &clip_y2);
    	cairo_set_line_width (cr, dx);
     
    	/* On dessine les axes */
    	cairo_set_source_rgb (cr, 0.0, 1.0, 0.0);
    	cairo_move_to (cr, clip_x1, 0.0);
    	cairo_line_to (cr, clip_x2, 0.0);
    	cairo_move_to (cr, 0.0, clip_y1);
    	cairo_line_to (cr, 0.0, clip_y2);
    	cairo_stroke (cr);
     
    	/* On rajoute les points de la coube en les reliant par une droite */
    	for (i = clip_x1; i < clip_x2; i += dx)
    		cairo_line_to (cr, i, f (i));
     
    	/* On dessine la courbe */
    	cairo_set_source_rgba (cr, 1, 0.2, 0.2, 0.6);
    	cairo_stroke (cr);
     
    	cairo_destroy (cr);
    	return FALSE;
    }
     
     
    int
    main (int argc, char **argv)
    {
    	GtkWidget *window;
    	GtkWidget *da;
     
    	gtk_init (&argc, &argv);
     
    	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    	gtk_window_set_default_size (GTK_WINDOW (window), WIDTH, HEIGHT);
    	gtk_window_set_title (GTK_WINDOW (window), "Affichage de courbe");
    	g_signal_connect (G_OBJECT (window), "delete-event", gtk_main_quit, NULL);
     
    	da = gtk_drawing_area_new ();
    	gtk_container_add (GTK_CONTAINER (window), da);
     
    	g_signal_connect (G_OBJECT (da), 
    			"expose-event", 
    			G_CALLBACK (on_expose_event), 
    			NULL);
     
    	gtk_widget_show_all (window);
    	gtk_main ();
     
    	return 0;
    }
    @Slookeur: pourrais tu poster une version minimale de ton programme qui reproduise le bug ?

  18. #38
    Membre du Club
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2009
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2009
    Messages : 61
    Points : 54
    Points
    54
    Par défaut Re, après tout ce temps ...
    Bonjour à tous et à toutes,

    depuis que j'ai initié cette discussion, j'ai résolu mais problèmes de comportement ... en utilisant effectivement une GtkDrawingArea.

    Bout de code qui fonctionne pour moi en exemple, ici je crée une fenêtre
    contenant (entre autres) une GtkDrawingArea, et j'utilise le 'expose_event'
    comme signal pour l'actualiser, cela fonctionne très bien, sous linux (Compiz, Metacity ... ou autre),
    Windows (Xp, Vista, 7), et MacOSX.

    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
     
    GtkWidget * create_Curve (char * namecurve, int * idcurve)
    {
      GtkWidget * Curve;
      GtkWidget * Cvbox;
      GtkWidget * menu;
      GtkWidget * menudata, * menucurve;
      GtkWidget * menud, * menuc;
      GtkWidget * savecurveas;
      GtkWidget * savecurve;
      GtkWidget * editcurve;
      GtkWidget * separatormenu;
      GtkWidget * closecurve;
      GtkAccelGroup * accel_group;
      int i, j;
     
      accel_group = gtk_accel_group_new ();
      Curve = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_window_set_title (GTK_WINDOW(Curve), namecurve);
      gtk_window_set_default_size (GTK_WINDOW(Curve), 840, 677);
      gtk_window_set_resizable (GTK_WINDOW (Curve), TRUE);
      Cvbox = gtk_vbox_new (FALSE, 0);
      gtk_container_add (GTK_CONTAINER (Curve), Cvbox);
      menu = gtk_menu_bar_new ();
      gtk_box_pack_start (GTK_BOX (Cvbox), menu, FALSE, TRUE, 0);
      menudata = gtk_menu_item_new_with_mnemonic (("_Data"));
      gtk_container_add (GTK_CONTAINER (menu), menudata);
      menud = gtk_menu_new ();
      gtk_menu_item_set_submenu (GTK_MENU_ITEM (menudata), menud);
      savecurveas = gtk_image_menu_item_new_from_stock ("gtk-save-as", accel_group);
      gtk_container_add (GTK_CONTAINER (menud), savecurveas);
      separatormenu = gtk_separator_menu_item_new ();
      gtk_container_add (GTK_CONTAINER (menud), separatormenu);
      gtk_widget_set_sensitive (separatormenu, FALSE);
      closecurve = gtk_image_menu_item_new_from_stock ("gtk-close", accel_group);
      gtk_container_add (GTK_CONTAINER (menud), closecurve);
      menucurve = gtk_menu_item_new_with_mnemonic (("_Curve"));
      gtk_container_add (GTK_CONTAINER (menu), menucurve);
      menuc = gtk_menu_new ();
      gtk_menu_item_set_submenu (GTK_MENU_ITEM (menucurve), menuc);
      editcurve = gtk_image_menu_item_new_with_mnemonic (("E_dit curve"));
      gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM(editcurve), gtk_image_new_from_file(PACKAGE_EDIT));
      gtk_container_add (GTK_CONTAINER (menuc), editcurve);
      savecurve = gtk_image_menu_item_new_with_mnemonic (("_Export image"));
      gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM(savecurve), gtk_image_new_from_file(PACKAGE_PNG));
      gtk_container_add (GTK_CONTAINER (menuc), savecurve);
     
      curves[* idcurve] -> plot = gtk_drawing_area_new();
      gtk_box_pack_start (GTK_BOX (Cvbox), curves[* idcurve] -> plot, TRUE, TRUE, 0);
     
      g_signal_connect ((gpointer)curves[* idcurve] -> plot, "expose_event", G_CALLBACK(to_show), GINT_TO_POINTER(* idcurve));
      g_signal_connect ((gpointer)Curve, "delete_event", G_CALLBACK(curve_hide), GINT_TO_POINTER(* idcurve));
      g_signal_connect ((gpointer)savecurveas, "activate", G_CALLBACK(write_curve), GINT_TO_POINTER(* idcurve));
      g_signal_connect ((gpointer)savecurve, "activate", G_CALLBACK(save_image), GINT_TO_POINTER(* idcurve));
      g_signal_connect ((gpointer)editcurve, "activate", G_CALLBACK(edit_image), GINT_TO_POINTER(* idcurve));
      g_signal_connect ((gpointer)closecurve, "activate", G_CALLBACK(hide_curve), GINT_TO_POINTER(* idcurve));
      gtk_window_add_accel_group (GTK_WINDOW (Curve), accel_group);
     
      return Curve;
    }
    Le code source complet du programme que j'ai développé, ISAACS, est disponible à cette adresse (inclus les fichiers Code::blocks):

    http://isaacs.sourceforge.net

    @pvincent: je suis physicien moi aussi, une des idées derrière le développpement d'ISAACS (Interactive Structure Analysis of Amorphous and Crystalline Systems) était de proposer un programme permettant à un utilisateur non averti, un étudiant par exemple, de réaliser certain calculs physiques complexes (en Fortran 90, car déjà partiellement codés pour http://rings-code.sourceforge.net, que j'ai également écris et // en MPI) puis de visualiser directement les résultats.
    Je n'ai pas rencontré de problèmes de communication entre les compilateurs, j'utilise gfortran et gcc, j'avoue avoir essayé les compilateurs Intel sans succès, mais pour le moment tout marche très bien avec les GNU, et le seul prix à payer a été le temps nécessaire à comprendre la communication entre les 2 langages ... maintenant tout est ok ... je touche du bois.
    Je dois avouer être plutôt fière de mon programme, et vous invite à le tester.

    Merci à tout le monde.

  19. #39
    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
    Points : 2 002
    Points
    2 002
    Par défaut
    Pour réaliser ton interface graphique, je te conseille de t'orienter vers Glade + GtkBuilder, et GtkUIManager.

Discussions similaires

  1. Zone de Dessin dans une fenêtre [GTK 3 & Cairo]
    Par Twice22 dans le forum GTK+ avec C & C++
    Réponses: 14
    Dernier message: 04/05/2013, 10h41
  2. Comportement de Gtk avec Gtk.Main.Timeout
    Par Invité dans le forum GTK+ avec C & C++
    Réponses: 8
    Dernier message: 07/12/2011, 19h33
  3. Fenêtres multiples avec la librairie SDL
    Par pierrev1 dans le forum SDL
    Réponses: 4
    Dernier message: 10/12/2006, 11h36
  4. Commander des fenêtres GTK avec le shell
    Par clebig dans le forum GTK+ avec C & C++
    Réponses: 2
    Dernier message: 31/07/2006, 11h58
  5. [GTK] avec Dev-C++
    Par touronster dans le forum Dev-C++
    Réponses: 12
    Dernier message: 30/06/2005, 20h15

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