Oui tu dois implémenter toi-même les fonctions de dessin dont tu as besoin. Pour revenir à ton projet tracer une ligne verticale ne devrait pas te poser beaucoup de problème.
Au pire regarde cet exemple de la documentation officielle.
Oui tu dois implémenter toi-même les fonctions de dessin dont tu as besoin. Pour revenir à ton projet tracer une ligne verticale ne devrait pas te poser beaucoup de problème.
Au pire regarde cet exemple de la documentation officielle.
Utilisation de Glade avec Gtk+
Code::Blocks et Gtk+ sous Windows
Programmation orientée objet avec Gtk+ v3
- N'oubliez pas de consulter les FAQ Gtk et les cours et tutoriels Gtk
Mais alors comment va marcher ma callback de tracage si je n'utilise QUE des pixbufs ?
Une fois que j'ai dessiné dans le Pixbuf, fais une capture du pixbuf sauf la colonne de gauche ainsi :
Le drawing pixbuf est celui qui va être affiché dans le GtkDrawingArea.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 previous_pixbuf = gdk_pixbuf_copy (gdk_pixbuf_new_subpixbuf (drawing_pixbuf,1,0, width-1, height)) ;
Mais ensuite comment faire pour "coller" ensuite le previous_pixbuf sur la gauche du nouveau pixbuf ? Je vais tenter avec
Je vous reviens avec les résultats
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 gdk_pixbuf_scale (previous_pixbuf, drawing_pixbuf, 0,0, width, height, 0,0,0,0, GDK_INTERP_NEAREST)![]()
Bon, en fait avec la nouvelle méthode, plus rien ne marche et j'ai des warning dans tous les sensJ'ai plein de problemes qui se sont rajouté mais je pense que c'est dû à plusieurs choses que je n'ai pas saisi.
Voilà ce que j'ai fait :
1) Dans le fichier interface.c, après la création du GtkDrawingArea, je crée un GdkPixbuf de la même taille (premier probleme, il n'arrive pas à récupérer la taille).
2) Je rajoute la callback cb_graph à la Main Loop, toute les seconde. En entrée/sortie se trouve le pointeur vers le GtkPixbuf créé.
3) Dans cb_graph :
Dois recopier un pixbuffer SRC dans un autre DEST Je ne sais pas comment faire car gdk_pixbuf_scale (previous_pixbuf, drawing_pixbuf, 0,0, width, height, 0,0,0,0, GDK_INTERP_NEAREST) me pose des warning sur les dimensions que je ne comprend pas.
Le pixbuf Dest à une colonne de plus que SRC. Je veux que la colonne de droite de DEST (qui n'est autre que le GdkPixbuf d'entree sortie) soit libre pour le dessins qui suit.
Puis je dessine mon nouveau pixel.
A quel moment je dois dessiner le pixbuf dans le GtkDrawingArea ??
Sans encore parler le expose_event, je n'ai déjà plus rien qui marche.
Sur ce coup il doit y en avoir un qui doit commencer à se dire: " Avant que je suive les recommandations de ce forum j'avais un truc qui marchait à peu prêt bien. Maintenant c'est devenu n'importe quoi et je comprends plus rien!".
Bon ben faut que je défasse un peu les nœuds alors. Comme je vois que tu te donnes quand même beaucoup de mal je te propose de te fournir un exemple le plus court possible sur comment implémenter le principe que j'essaie de t'exposer tout le long de ce fil. J'avoue ne pas être forcément clair dans mes explications alors parfois un dessin vaut mieux que de longs discours. (Les longs discours ça commence déjà là!
)
Donc voici le but de l'exemple qui va suivre :
- Créer une fenêtre (fenetre_principale) qui contiendra un simple GtkDrawingArea (drawing).
- Initialiser (draw_realize()) un pixbuf (Pixbuf_principal) de couleur noir qui sera inséré dans le GtkDrawingArea.
- Créer une fonction (invert_pixbuf()) qui inversera la couleur du pixbuf toutes les secondes.
- Créer une fonction d'affichage du tout (drawing_expose()).
J'ai volontairement augmenté le code dans la fonction appelée toutes les secondes pour te montrer un traitement de pixbuf. C'est juste pour l'exemple. J'aurais pu ici traiter directement le pixbuf principal.
Tout ceci étant dit (ou plutôt écrit), passons tout de même au code. N'hésite pas à poser des questions si certaines tournures de code te paraissent venir de l'espace.
Au passage tu remarqueras que je n'utilise aucune variable déclarée en globale.
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 #include <gtk/gtk.h> struct _SDraw { GtkWidget *drawing; GdkPixbuf *Pixbuf_principal; }; typedef struct _SDraw SDraw; gboolean drawing_expose(GtkWidget *widget, GdkEventExpose *event, SDraw *pointeurs) { // on teste toujours si le pixbuf != NULL if (!pointeurs->Pixbuf_principal) { g_print("Le pixbuf n'est pas valide. Pas d'affichage possible.\n"); return TRUE; } g_print("Le pixbuf est valide. Donc je peux l'afficher.\n"); // On affiche simplement le GdkPixbuf dans le GtkDrawingarea gdk_draw_pixbuf(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], pointeurs->Pixbuf_principal, 0, 0, 0, 0, gdk_pixbuf_get_width(pointeurs->Pixbuf_principal), gdk_pixbuf_get_height(pointeurs->Pixbuf_principal), GDK_RGB_DITHER_MAX, 0, 0); return TRUE; } gboolean invert_pixbuf(SDraw *pointeurs) { gint i; guchar *pixel=NULL; GdkPixbuf *pixbuf_tmp=NULL; // on teste toujours si le pixbuf != NULL if (!pointeurs->Pixbuf_principal) return TRUE; g_print("Le pixbuf est valide. Alors je peux inverser sa couleur.\n"); // On inverse tous les pixels (on passe du blanc au noir et inversement) pixbuf_tmp=gdk_pixbuf_copy(pointeurs->Pixbuf_principal); // On récupère le pointeur des pixels de l'image pixel=gdk_pixbuf_get_pixels(pixbuf_tmp); for (i=0; i < gdk_pixbuf_get_width(pixbuf_tmp)*gdk_pixbuf_get_height(pixbuf_tmp)*3; i++) pixel[i]=pixel[i]^255; // On recopie le nouveau pixbuf dans le pointeur principal g_object_unref(pointeurs->Pixbuf_principal); pointeurs->Pixbuf_principal=gdk_pixbuf_copy(pixbuf_tmp); g_object_unref(pixbuf_tmp); /*le fait de recopier le pixbuf, de traiter la copie pour finalement le recopier de nouveau n'est là que pour l'exemple. Ce code est inutile au demeurant.*/ // Il faut maintenant demander la mise à jour du GtkDrawingArea. drawing_expose(pointeurs->drawing, NULL, pointeurs); return TRUE; } void drawing_realize(GtkWidget *widget, SDraw *pointeurs) { gint i=0; guchar *pixel=NULL; g_print("Cette fonction n'est appellée qu'une seule fois..\n"); // initialisation du pixbuf. pointeurs->Pixbuf_principal=gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE,8,200,200); // L'image est mise au noir. // On récupère le pointeur des pixels de l'image pixel=gdk_pixbuf_get_pixels(pointeurs->Pixbuf_principal); for (i=0; i < gdk_pixbuf_get_width(pointeurs->Pixbuf_principal)*gdk_pixbuf_get_height(pointeurs->Pixbuf_principal)*3; i++) pixel[i]=0; // Mise en place de l'appel à la fonction de tracé toutes les secondes. g_timeout_add_seconds(1, (GSourceFunc)invert_pixbuf, pointeurs); } void init_window(SDraw *pointeurs) { GtkWidget *fenetre_principale=NULL; /* création de la fenêtre principale */ fenetre_principale=gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(fenetre_principale), "test draw gdkpixbuf"); // Création d'une entrée texte pointeurs->drawing=gtk_drawing_area_new(); gtk_container_add(GTK_CONTAINER(fenetre_principale), pointeurs->drawing); /* On connecte une fonction qui va initiliser le GtkDrawingarea ainsi que le pixbuf principal*/ g_signal_connect(G_OBJECT(pointeurs->drawing), "realize", (GCallback)drawing_realize, pointeurs); /* On connecte aussi une fonction qui va s'occuper de l'affichage proprement dit du pixbuf.*/ g_signal_connect(G_OBJECT(pointeurs->drawing), "expose_event", (GCallback)drawing_expose, pointeurs); // Affection des signaux pour fermeture de l'application g_signal_connect(G_OBJECT(fenetre_principale), "destroy", (GCallback)gtk_main_quit, NULL); // Affichage de la fenêtre gtk_widget_show_all(fenetre_principale); } gint main(gint argc,gchar **argv) { SDraw *Pointeurs=g_malloc(sizeof(SDraw)); Pointeurs->drawing=NULL; Pointeurs->Pixbuf_principal=NULL; gtk_init(&argc, &argv); init_window(Pointeurs); gtk_main(); g_free(Pointeurs); return 0; }
Utilisation de Glade avec Gtk+
Code::Blocks et Gtk+ sous Windows
Programmation orientée objet avec Gtk+ v3
- N'oubliez pas de consulter les FAQ Gtk et les cours et tutoriels Gtk
Merci beaucoup Gerald3d.
Ton exemple est très clair et je te remercie d'avoir passé du temps à le faire. Je suis sûr que ça pourra servir à d'autres également. Je commence à vraiment à y voir plus clair.
Si je t'avais à côté je te payerais une bonne mousse !
Bon ! Je m'y remet !Merci !
Hum, bien fraiche à la terrasse d'un café...![]()
Utilisation de Glade avec Gtk+
Code::Blocks et Gtk+ sous Windows
Programmation orientée objet avec Gtk+ v3
- N'oubliez pas de consulter les FAQ Gtk et les cours et tutoriels Gtk
Resalut
Je me permet de poser une autre question, toujours dans ce même sujet.
Lorsque dans mon main(), je souhaite enregistrer dans une variable la donnée qui est éventuellement passée en argument de ligne de commande (un path vers un fichier de configuration) (dans argv[0]), je fais ce traitement AVANT l'appel à gtk_init(), AVANT le dessin de l'interface, et AVANT de lancer la Main Loop.
Pourtant, le traitement n'est fait qu'à la fermeture de la fenêtre, ce qui est bien évidemment génant car ma variable reste vide jusqu'à la fermeture. Comment pallier à ce problème ?
Ca doit venir de ton code puisque les arguments en ligne de commande son totalement indépendants de GTK+.
Utilisation de Glade avec Gtk+
Code::Blocks et Gtk+ sous Windows
Programmation orientée objet avec Gtk+ v3
- N'oubliez pas de consulter les FAQ Gtk et les cours et tutoriels Gtk
Partager