Bonjour,

Je suis en train de me heurter à un problème tout simple (que j'ai déjà résolu dans le passé) dans l'usage de la librairy cairo.

Voici un exemple bidon qui marche bien, dans lequel je défini une GtkDrawingArea qui est le seul élément de la fenêtre principale, et j'y trace un trait dedans.

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
#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include <cairo.h>
#include <gtk/gtk.h>
#include <glib.h>
#include <glib/gstdio.h>
 
GtkWidget *pWindow; /*fenetre principale */
GtkWidget *drawarea; /* drawing area */
 
int main (int argc, char *argv[])
{
    void OnDestroy(GtkWidget *pWidget, gpointer pData); /* fonction call back destroy */
    gboolean on_expose_event(GtkWidget * widget, GdkEventExpose * event, gpointer userdata);
    gtk_init(&argc, &argv);
    /* création de la fenetre */
    pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    /* définition des paramètres de la fenetre */
    gtk_window_set_default_size(GTK_WINDOW(pWindow), 200, 200);
    drawarea=gtk_drawing_area_new();
    gtk_container_add (GTK_CONTAINER(pWindow), drawarea);
    g_signal_connect(G_OBJECT(pWindow), "destroy", G_CALLBACK(gtk_main_quit), NULL);
    g_signal_connect(G_OBJECT(drawarea), "expose_event", G_CALLBACK(on_expose_event), NULL);
    gtk_widget_show_all(pWindow);
    gtk_main();
    return EXIT_SUCCESS;
}
gboolean on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer userdata)
{
    cairo_t *cr=NULL;
    cr=gdk_cairo_create(widget->window);
    cairo_set_source_rgb(cr, .1, .0, .0);
    cairo_set_line_width(cr, 2.0);
    cairo_move_to(cr, 10., 10.);
    cairo_line_to(cr,100.,100.);
    cairo_stroke(cr);
    cairo_destroy(cr);
    return FALSE;
}
Tout marche correctement. So far so good.

A présent, un autre exemple bidon où la GtkDrawingArea est cette fois-ci un élément d'une GtkHBox :

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
#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include <cairo.h>
#include <gtk/gtk.h>
#include <glib.h>
#include <glib/gstdio.h>
 
GtkWidget *pWindow; /*fenetre principale */
GtkWidget *drawarea; /* drawing area */
GtkWidget *pHBox; /* une box horizontal */
GtkWidget *quit; /* bouton quit */
 
int main (int argc, char *argv[])
{
    void OnDestroy(GtkWidget *pWidget, gpointer pData); /* fonction call back destroy */
    gboolean on_expose_event(GtkWidget * widget, GdkEventExpose * event, gpointer userdata);
    gtk_init(&argc, &argv);
    /* création de la fenetre */
    pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    /* définition des paramètres de la fenetre */
    gtk_window_set_default_size(GTK_WINDOW(pWindow), 200, 200);
    drawarea=gtk_drawing_area_new();
    pHBox=gtk_hbox_new(FALSE, 0);
    quit=gtk_button_new_with_label(" Quit ");
    gtk_box_pack_start(GTK_BOX(pHBox), quit, FALSE, TRUE, 1);
    gtk_box_pack_start(GTK_BOX(pHBox), drawarea, FALSE, TRUE, 1);
    gtk_container_add (GTK_CONTAINER(pWindow), pHBox);
    g_signal_connect(G_OBJECT(pWindow), "destroy", G_CALLBACK(gtk_main_quit), NULL);
    g_signal_connect(G_OBJECT(drawarea), "expose_event", G_CALLBACK(on_expose_event), NULL);
    g_signal_connect(G_OBJECT(quit), "clicked", G_CALLBACK(gtk_main_quit), NULL);
    gtk_widget_show_all(pWindow);
    gtk_main();
    return EXIT_SUCCESS;
}
gboolean on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer userdata)
{
    cairo_t *cr=NULL;
    cr=gdk_cairo_create(widget->window);
    cairo_set_source_rgb(cr, .1, .0, .0);
    cairo_set_line_width(cr, 2.0);
    cairo_move_to(cr, 10., 10.);
    cairo_line_to(cr,100.,100.);
    cairo_stroke(cr);
    cairo_destroy(cr);
    return FALSE;
}
Et bien, impossible de dessiner dedans, et je n'arrive pas à trouver pourquoi, alors que j'ai fait ce genre de trucs des centaines de fois par le passé. Ca ressemble à une erreur d'étourderie, mais je ne vois pas. Si une âme charitable pouvait m'aider..

D'avance merci, Eric.