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 d'un drawing area


Sujet :

GTK+ avec C & C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 87
    Par défaut Affichage d'un drawing area
    Bonjour,
    j'ai cherché à droite et à gauche et je n'arrive pas à résoudre mon problème,
    j'essaye juste d'afficher un rectangle rouge dans un drawing_area, la actuellement, avec le code ci dessous, je n'ai rien, juste la fenetre gtk.

    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
    #include <stdlib.h>
    #include <stdio.h> 
    #include <gtk/gtk.h>
     
    #define LONGUEUR 650
    #define LARGEUR 300
     
    GtkWidget *dessin;
    GdkPixmap *pixmap = NULL;;
     
    static gboolean realisation(GtkWidget *dessin,GdkEventConfigure *event)
    {
      GdkColor rouge;
      rouge.pixel=0;
      rouge.red=0xFFFF;
      rouge.green=0;
      rouge.blue=0;
     
      GdkGC *kontext = gdk_gc_new (dessin->window);
      gdk_gc_set_foreground (kontext, &rouge);
     
      pixmap = gdk_pixmap_new(dessin->window,dessin->allocation.width,dessin->allocation.height,-1);
     
      gdk_draw_rectangle(pixmap,kontext,TRUE,50,50,50,50);
     
      gtk_widget_queue_draw(dessin);
     
      return TRUE;
    }
     
     
    void start_gtk(int argc,char **argv)
    {   
    	gtk_init (&argc, &argv);  
     
      GtkWidget *win = gtk_window_new (GTK_WINDOW_TOPLEVEL);    
      gtk_container_set_border_width (GTK_CONTAINER (win), 0);
      gtk_window_set_title (GTK_WINDOW (win), "rectangle");
      gtk_window_set_position (GTK_WINDOW (win), GTK_WIN_POS_CENTER);
      gtk_window_set_default_size(GTK_WINDOW(win), LONGUEUR, LARGEUR);
      g_signal_connect (win, "destroy", gtk_main_quit, NULL);
      gtk_widget_realize (win);
     
      GtkWidget *box = gtk_vbox_new (FALSE, 0);
      gtk_container_add (GTK_CONTAINER (win), box);
     
      GtkWidget *dessin = gtk_drawing_area_new();
      gtk_drawing_area_size(GTK_DRAWING_AREA(dessin),200, 400);
    	gtk_container_add (GTK_CONTAINER (box), dessin);
     
      g_signal_connect(G_OBJECT(dessin), "realize", G_CALLBACK(realisation), NULL);
     
    	gtk_widget_show_all (win);	
    	gtk_main ();    
    }
     
    int main(int argc,char **argv)
    {
    	start_gtk(argc,argv);
    	return 0;
    }
    Le code est compilable sans erreurs et je suis sous windows.

    Merci de votre aide

  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
    Pour faire simple il faut connecter le signal "expose-event" au drawingarea. Ensuite ton pixmap ne sert à rien et en plus il alloue un espace dans le tas qui n'est jamais libéré (mon linux n'a pas trop apprécié ).
    Enfin attention aux déclarations de variable en local et global. Tu déclares dessin dans les deux par moment. Ca pose quelques problèmes de compréhension pour nous et pour toi sans parler des segdefault que ca génère.
    Un petit détail pour finir. Lorsque tu crées une couleur il faut l'enregistrer dans le colormap avant de pouvoir l'utiliser.

    Histoire de rendre tout ca lisible j'ai modifié ton code en conséquence :
    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
    #include <stdlib.h>
    #include <stdio.h> 
    #include <gtk/gtk.h>
     
    #define LONGUEUR 650
    #define LARGEUR 300
     
     
    //GdkPixmap *pixmap = NULL;;
     
    gboolean Affichage(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
    {
      GdkColor rouge;
      GdkColormap *colormap;
      rouge.red=0xFFFF;
      rouge.green=0;
      rouge.blue=0;
    printf("Affichage\n");
     
      GdkGC *kontext = gdk_gc_new (widget->window);
      colormap = gdk_drawable_get_colormap (widget->window);
      gdk_colormap_alloc_color (colormap, &rouge, FALSE, FALSE);
      gdk_gc_set_foreground (kontext, &rouge);
     
    //  pixmap = gdk_pixmap_new(widget->window,widget->allocation.width,widget->allocation.height,-1);
     
      gdk_draw_rectangle(widget->window, kontext,TRUE,50,50,50,50);
     
      gtk_widget_queue_draw(widget);
     
    	return FALSE;
    }
     
    static gboolean realisation(GtkWidget *dessin, GdkEventConfigure *event)
    {
      GdkColor rouge;
      rouge.pixel=0;
      rouge.red=0xFFFF;
      rouge.green=0;
      rouge.blue=0;
    printf("realisation\n"); 
      GdkGC *kontext = gdk_gc_new (dessin->window);
      gdk_gc_set_foreground (kontext, &rouge);
    /*	
      pixmap = gdk_pixmap_new(dessin->window,dessin->allocation.width,dessin->allocation.height,-1);
     
      gdk_draw_rectangle(pixmap,kontext,TRUE,50,50,50,50);
     
      gtk_widget_queue_draw(dessin);
    */ 	
      return FALSE;
    }
     
     
    void start_gtk(int argc,char **argv)
    {
    	gtk_init (&argc, &argv);  
     
      GtkWidget *win = gtk_window_new (GTK_WINDOW_TOPLEVEL);    
      gtk_container_set_border_width (GTK_CONTAINER (win), 0);
      gtk_window_set_title (GTK_WINDOW (win), "rectangle");
      gtk_window_set_position (GTK_WINDOW (win), GTK_WIN_POS_CENTER);
      gtk_window_set_default_size(GTK_WINDOW(win), LONGUEUR, LARGEUR);
      g_signal_connect (win, "destroy", gtk_main_quit, NULL);
      gtk_widget_realize (win);
     
      GtkWidget *box = gtk_vbox_new (FALSE, 0);
      gtk_container_add (GTK_CONTAINER (win), box);
     
      GtkWidget *dessin = gtk_drawing_area_new();
      gtk_drawing_area_size(GTK_DRAWING_AREA(dessin),200, 400);
    	gtk_container_add (GTK_CONTAINER (box), dessin);
     
      g_signal_connect(G_OBJECT(dessin), "realize", G_CALLBACK(realisation), NULL);
      g_signal_connect(G_OBJECT(dessin), "expose-event", G_CALLBACK(Affichage), NULL);
     
    	gtk_widget_show_all (win);	
    	gtk_main ();    
    }
     
    int main(int argc,char **argv)
    {
    	start_gtk(argc,argv);
    	return 0;
    }
    P.S. : la fonction realisation(); peut être purement supprimer ici.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 87
    Par défaut
    Merci

    en effet il y avait pas mal d'erreurs bête,

    cependant je suis obligé de passer par le signal "expose-event" ou tout autre signal, j'aimerai afficher quelque chose directement sans qu'un signal ait besoin d'être émit ?

  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
    Passage obligé! Ce signal est émis à chaque fois que le widget, ou une partie du widget, doit être redessiné.

  5. #5
    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
    Le signal "expose-event" est émis chaque fois qu'une zone de ton widget doit être dessinée, suite à un redimensionnement, une fenêtre qui le cachait qui est déplacée et le découvre, etc.

    C'est en réponse à cet évènement que tu dois dessiner. C'est ainsi que fonctionne le système de signaux : tu dis à la main loop en connectant le signal "préviens moi quand tel évènement survient", et une fois qu'il survient (et donc que tu as une action à faire) elle appelle ta callback.

    Tu n'es cependant pas obligé de redessiner tout le widget, tu peux te contenter de la zone qui a été invalidée (conseillé pour de meilleures performances). Cette zone se trouve dans le champ event->area.

  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
    J'ajoute que gtk_widget_queue_draw ne devrait pas être appelé, car il renvoie une demande d'invalidation de la zone occupée à l'écran par le widget, ce qui doit provoquer à mon avis l'émission du signal et appel de la calback en boucle... La doc spécifie d'ailleurs que c'est à n'utiliser que quand on développe un nouveau widget, ce qui n'est pas le cas ici...

    Pour finir, je te conseille de lire le code des applications exemple "pixbuf" et "drawing area" contenues dans gtk-demo (livré avec GTK).

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

Discussions similaires

  1. Drawing area - problème d'affichage
    Par Bertrand_g dans le forum GTK+ avec C & C++
    Réponses: 3
    Dernier message: 20/03/2008, 21h59
  2. Dessiner sur une drawing area
    Par Fibus dans le forum GTK+ avec C & C++
    Réponses: 8
    Dernier message: 19/12/2007, 16h57
  3. drawing area et itérations
    Par Rniamo dans le forum GTK+ avec C & C++
    Réponses: 7
    Dernier message: 07/11/2007, 19h00
  4. Drawing area
    Par Blackshade dans le forum GTK+ avec PHP
    Réponses: 4
    Dernier message: 06/06/2007, 16h51
  5. Image de fond dans un drawing area
    Par smux dans le forum GTK+ avec C & C++
    Réponses: 1
    Dernier message: 15/09/2006, 11h17

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