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 :

Dessiner du texte ?


Sujet :

GTK+ avec C & C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de tintin72
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    663
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 663
    Par défaut Dessiner du texte ?
    Bonjour,

    J'aimerais savoir comment dessiner du texte avec GTK.
    Je n'ai pas trouvé grand chose là dessus.
    Bien sur il y a la fonction gdk_draw_text () mais je n'ai pas vu d'exemples d'utilisation.
    Certain disent qu'il faut utiliser la librairie Pango pour dessiner du texte mais là encore trés peu d'information.

    Voici une application ultra simple:
    Une fenêtre et une drawing area avec un fond blanc:

    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
     
    #define WIDTH 500
    #define HEIGHT 300
     
     
    static GdkPixmap *pixmap = NULL;
     
    void refresh_cb(GtkWidget *draw_area, gpointer data)
    {
       if (pixmap == NULL)
       {
        pixmap = gdk_pixmap_new(draw_area->window, 500, HEIGHT, -1);
        gdk_draw_rectangle(pixmap, draw_area->style->white_gc, TRUE, 0, 0, WIDTH, HEIGHT);
       }
       gdk_draw_pixmap(draw_area->window, draw_area->style->black_gc, pixmap, 0,0,0,0, WIDTH, HEIGHT);
    }
     
     
    int main(int argc, char **argv)
    {
        GtkWidget *pWin;
        GtkWidget *pDrawArea;
        GtkWidget *pVBox;
        gtk_init(&argc, &argv);
     
     
        pWin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_window_set_default_size(GTK_WINDOW(pWin), WIDTH, HEIGHT);
        g_signal_connect(G_OBJECT(pWin), "destroy", G_CALLBACK(gtk_main_quit), NULL);
     
        pVBox = gtk_vbox_new(FALSE, 4);
        gtk_container_add(GTK_CONTAINER(pWin), pVBox);
        pDrawArea = gtk_drawing_area_new ();
        gtk_widget_set_size_request (pDrawArea, WIDTH, HEIGHT);
        g_signal_connect(G_OBJECT(pDrawArea),"event",G_CALLBACK(refresh_cb), NULL);
        gtk_box_pack_start(GTK_BOX(pVBox), pDrawArea, TRUE, TRUE, 0);
     
        gtk_window_set_title(GTK_WINDOW(pWin), "GTK-Win");
        gtk_widget_show_all(pWin);
        gtk_main();
        return EXIT_SUCCESS;
    }
    Est ce que quelqu'un pourrait me montrer comment utiliser gdk_draw_text () afin d'afficher un texte (hello world par ex) au milieu de la fenêtre ?

    D'avance merci

  2. #2
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Par défaut
    Citation Envoyé par tintin72
    Est ce que quelqu'un pourrait me montrer comment utiliser gdk_draw_text () afin d'afficher un texte (hello world par ex) au milieu de la fenêtre ?
    gdk_draw_text est obsolète, il faut utiliser gdk_draw_layout (ok ça t'aide pas des masse mais je vais essayer de regarder ça pendant le week-end )

  3. #3
    Membre éclairé Avatar de tintin72
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    663
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 663
    Par défaut
    mais je vais essayer de regarder ça pendant le week-end
    Super sympa, merci

  4. #4
    Membre éclairé Avatar de tintin72
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    663
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 663
    Par défaut
    Aprés avoir fouillé un peu partout sur le net je suis arrivé à enfin affiché quelque chose comme 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
     
    void refresh_cb(GtkWidget *draw_area, gpointer data)
    {
       if (pixmap == NULL)
       {
        pixmap = gdk_pixmap_new(draw_area->window, WIDTH, HEIGHT, -1);
        gdk_draw_rectangle(pixmap, draw_area->style->white_gc, TRUE, 0, 0, WIDTH, HEIGHT);
       }
       gdk_draw_pixmap(draw_area->window, draw_area->style->black_gc, pixmap, 0,0,0,0, WIDTH, HEIGHT); 
     
       GdkGC *gc = gdk_gc_new(pixmap); //créé un contexte graphique
       PangoLayout *layout = gtk_widget_create_pango_layout (draw_area, "Hello World!!");
       gdk_draw_layout(pixmap, gc, 20, 20, layout);
    }
    Je suis également arrivé à afficher des valeurs d'entier avec sprintf comme 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
    17
    18
    19
    20
    21
    22
    23
     
    #define HFONT 15
     
    void refresh_cb(GtkWidget *draw_area, gpointer data)
    {
       char txtLnBuf[512];
       int i;
     
       if (pixmap == NULL)
       {
        pixmap = gdk_pixmap_new(draw_area->window, WIDTH, HEIGHT, -1);
        gdk_draw_rectangle(pixmap, draw_area->style->white_gc, TRUE, 0, 0, WIDTH, HEIGHT);
       }
       gdk_draw_pixmap(draw_area->window, draw_area->style->black_gc, pixmap, 0,0,0,0, WIDTH, HEIGHT); 
       GdkGC *gc = gdk_gc_new(pixmap); //créé un contexte graphique
       PangoLayout *layout = gtk_widget_create_pango_layout (draw_area, txtLnBuf);
       for(i = 0; i < 10; i++)
       {
        sprintf(txtLnBuf, "Hello line : %d", i);
        pango_layout_set_text(layout, txtLnBuf, strlen(txtLnBuf)+1);
        gdk_draw_layout(pixmap, gc, 20, i * HFONT, layout);
       }
    }
    par contre j'ai un pb incompréhensible lorsque je passe une valeur à la fonction refresh_cb via le pointeur sur void.
    voici un exemple simple:

    dans le main
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
       int leTest = 39;
       code......
       g_signal_connect(G_OBJECT(pDrawArea),"event",G_CALLBACK(refresh_cb), &leTest);
    puis dans refresh_cb
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
      int *pInt = (int*)data; //recupère le pointeur en le castant
      code.....
     
      GdkGC *gc = gdk_gc_new(pixmap); //créé un contexte graphique
       PangoLayout *layout = gtk_widget_create_pango_layout (draw_area, txtLnBuf);
       sprintf(txtLnBuf, "Hello line : %d", *pInt);
       pango_layout_set_text(layout, txtLnBuf, strlen(txtLnBuf)+1);
       gdk_draw_layout(pixmap, gc, 20, 20, layout);
    et là, à la place du chiffre attendu j'ai une espèce de gribouilli (comme des nombre superposés), et je n'arrive vraiment pas à comprendre (le passage de pointeur est pourtant correctement effectué).
    peut être est ce que je fais une mauvaise utilisation des fonctions de dessin ?

  5. #5
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Par défaut
    Voilà ce que j'ai fait pour afficher du texte (version minimale) :
    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
    #include <pango/pango.h>
    #include <gtk/gtk.h>
     
    void cb_expose_event (GtkWidget *, gpointer);
     
    int main (int argc, char **argv)
    {
      GtkWidget *p_main_window = NULL;
     
      gtk_init (&argc, &argv);
      p_main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      {
        GtkWidget *p_drawing_area = NULL;
     
        p_drawing_area = gtk_drawing_area_new ();
        g_signal_connect (G_OBJECT (p_drawing_area), "expose_event",
                          G_CALLBACK (cb_expose_event), NULL);
        gtk_container_add (GTK_CONTAINER (p_main_window), p_drawing_area);
      }
      gtk_widget_show_all (p_main_window);
      gtk_main ();
      return 0;
    }
     
    void cb_expose_event (GtkWidget *p_widget, gpointer user_data)
    {
      PangoContext *p_context = NULL;
      PangoLayout *p_layout = NULL;
     
      p_context = gtk_widget_get_pango_context (p_widget);
      p_layout = pango_layout_new (p_context);
      pango_layout_set_text (p_layout, "Hello World !", -1);
      gdk_draw_layout (p_widget->window,
                       p_widget->style->fg_gc[GTK_WIDGET_STATE (p_widget)],
                       0,
                       0,
                       p_layout);
      g_object_unref (p_layout);
     
      (void)user_data;
    }

    Citation Envoyé par tintin72
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
       int leTest = 39;
       code......
       g_signal_connect(G_OBJECT(pDrawArea),"event",G_CALLBACK(refresh_cb), &leTest);
    Passer un pointeur sur une varaible locale n'est pas forcement une bonne idée, si tu fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int main (void)
    {
    [...]
      {
        int leTest = 39;
     
        g_signal_connect(G_OBJECT(pDrawArea),"event",G_CALLBACK(refresh_cb), &leTest);
      }
      gtk_main ();
      return 0;
    }
    je ne pense pas que cela fonctionne (la variable étant détruite lors de l'appel à gtk_main).

  6. #6
    Membre éclairé Avatar de tintin72
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    663
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 663
    Par défaut
    Merci pour ton code

    Effectivement il est beaucoup plus conforme à l'exemple du gtk reference manual.

    nb: toutefois il ne faut pas oublier de mettre dans le main
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    g_signal_connect(G_OBJECT(p_main_window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
    sans quoi la fenêtre se ferme mais l'application continue de tourner
    Passer un pointeur sur une varaible locale n'est pas forcement une bonne idée
    J'ai essayé la même chose en déclarant leTest en variable globale mais ça ne marche pas mieux.
    je ne pense pas que cela fonctionne (la varaible étant détruite lors de l'appel à gtk_main).
    si l'appel à gtk_main détruit les variables passées en paramètre, je ne comprend pas l'utilité du dernier argument de g_signal_connect().
    En effet, le mécanisme censé passer des données utilisateur devrait permettre de passer tout ce qu'on veut (c'est le cas avec d'autres toolkit).
    Peut être GTK a-t-il une autre philosophie du passage de données utilisateur ?

Discussions similaires

  1. [D7] comment dessiner du text le long d'un polyline
    Par pavlacki dans le forum Delphi
    Réponses: 5
    Dernier message: 24/06/2007, 13h40
  2. Améliorer le dessin du texte d'un TMenuItem
    Par Sunchaser dans le forum C++Builder
    Réponses: 1
    Dernier message: 16/06/2006, 23h35
  3. Dessiner du texte à l'écran
    Par rolkA dans le forum DirectX
    Réponses: 2
    Dernier message: 22/07/2003, 12h34

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