bonjour,
J'émerai utiliser la fonction gdk_pixbuf_rotate_simple mais elle ne prend que des multiples de 90.
J'ai besoin de faire un disque qui tourne sur une platine de mixage donc il faudrait que je puisse réglé précisément les degrés.
bonjour,
J'émerai utiliser la fonction gdk_pixbuf_rotate_simple mais elle ne prend que des multiples de 90.
J'ai besoin de faire un disque qui tourne sur une platine de mixage donc il faudrait que je puisse réglé précisément les degrés.
Tu ne vas pas aimer ma réponse. Gtk n'a pas de fonction de rotation au degré prés. Deux solutions s'offrent tout de même à toi :
- soit tu utilises une librairie externe (libimlib2 par exemple)
- soit tu te fais un plaisir de coder la fonction adéquate (l'idéal est d'utiliser la technique de transformation bilinéaire).
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
Comme tu doit t'en douter je préfaire la premier solution car je n'aime pas réinventer la roue.
Sa serai possible de me donner des infos sur cette librairie externe ?
Aisse qu'elle est Multi-plateforme?
Si oui comment on fait pour l'installer j'utilise code block et je suis sur linux UBUNTU 10.10 ?
Tu es sous Ubuntu, donc aucun soucis d'installation. Tu lance synaptic, tu fais une recherche sur imlib2, tu vas trouver le package "libimlib2-dev" que tu installes avec joie et bonne humeur.
Une fois fait tu trouveras la documentation à cet emplacement que tu pourras ouvrir dans ton navigateur préféré : /usr/share/doc/libimlib2-dev/html/index.html.
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
Pour le 1, mieux vaut utiliser cairo: http://cairographics.org/samples/image/
En effet.
Maintenant j'ai posté un post sur le sujet et comme je n'avais aucune réponse j'ai préféré donner une "autre solution".
Bien vu Liberforce.![]()
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
Pour cairo ses possible de le mélanger avec gdk pixbuf?
J’aurai préféré tout tout faire avec cairo mais tent qu'il n'existe pas de vrais tutorial en francais je préfaire évitter.
La dernier fois j'ai du demander des infos au conte goute pour gdk pixbuf sur le forum donc je n'ai plus assé de patience.
Est a se sujet combien sa me coûterai si je prenais des cours particuliers avec un programmeur qui connais l'anglais ?
Oui.
Mais cairo est plutôt sur une couche différente. GdkPixbuf, c'est juste une liste de valeurs de pixels décrivant une image. Pour dessiner, on utilise des GdkDrawable (GdkWindow, GdkPixmap), qui eux peuvent gérer les contraintes (palette de couleurs par exemple) de la surface sur laquelle tu veux dessiner, et qui se servent de GdkPixbuf. Tout cela va de toute façon disparaître à la sortie de GTK 3, où les GdkDrawable n'existeront plus, et tout passera par cairo.
Dans GTK 2, tu as néanmoins des fonctions pour faire cohabiter tout l'héritage de GDK avec cairo.
Et tu as donc par exemple la possibilité d'utiliser un pixbuf comme source cairo (la source dans cairo, c'est l'encre avec laquelle tu peins) avec gdk_cairo_set_source_pixbuf.
En revanche, une fois que tu as fait tes actions avec cairo, tu ne pourras plus vraiment manipuler le résultat avec GdkPixbuf, à moins de sauvegarder dans un fichier image et la relire ensuite (ou alors il y a un moyen que je ne connais pas).
De toute façon, GdkPixbuf est volontairement limité (les fonctions de dessins étaient dans GDK), et l'avenir c'est cairo, utilisable avec GTK2 > 2.8 et GTK3. Ce n'est donc pas du temps perdu.
C'est clair que la documentation française est inexistante. Mais avec un traducteur automatique, le nom des fonctions n'est pas dur à deviner...
cairo_arc dessine un arc de cercle, cairo_paint peint, cairo_stroke trace, etc.
Et les exemples sont bien fichus.
L'apprentissage de la programmation, ça demande de la patience. C'est de l'approche essai->erreur. On essaie quelque chose, ça ne marche pas, on tente autre chose, etc. jusqu'à ce qu'on y arrive.
Aucune idée...
La patience, j'en est mais je manque surtout de temps et quant c'est bien expliquer je mais 10 x moin de temps, alors que quant c'est le contraire je suis même pas sur d’arriver à la fin même quant j'ai déjà passé des jours a essayé de comprendre.
Pour google traduction généralement sa traduit très mal est encore faut-il que la documentation d'origine soi bien expliquer.
Et puis comme je les déjà dit par le passé j'ai un gros problème de dyslexie donc sa n’arrange pas les chose.
Comme j'ai du mal à tout mettre en ordre dans ma tête, plein de petit bou de code isolé c'est insuffisent, pour mieux comprendre j'ai besoin d'un code d'ensemble qui donne l'ordre des opérations à effectuer.
Mais après plusieurs heurs de recherche sur google j'ai trouver:
http://www.mono-lab.ch/?p=22
http://www.dil.univ-mrs.fr/~regis/CM-CAIRO/index.html
Maintenant pour comprendre il faudrai qu'on m'adapte se code(de gerald3d) avec cairo:
Désolé de vous déranger encore une fois, en eyent un code d'ensemble sa m'évite de poser pluns de question , ya que comme sa que j'arrive réailment à comprendre.#include <gtk/gtk.h>
/* Structure qui va nous servir à atteindre les différentes images à dessiner
* ainsi que différentes données nécessaire à la position de l'image
* courante déplacée.
*/
typedef struct
{
GdkPixbuf *MainPixbuf;
GdkPixbuf *SecondPixbuf;
gint XCurrentPosition; // Position X courante de SecondPixbuf
gint YCurrentPosition; // Position Y courante de SecondPixbuf
gint XPointer; // Position x de la souris lors du clic
gint YPointer; // Position y de la souris lors du clic.
gboolean ButtonPressedInPixbuf;
} MainData;
/* Fonction d'affichage du drawingarea. */
gboolean callback_expose_event(GtkWidget *widget, GdkEventExpose *event,
MainData *data)
{
/* On crée un nouveau contexte graphique. Permet de changer la couleur
* d'avant plan pour écrire du texte par exemple. Ici on n'en a besoin
* pour afficher les pixbuf.
*/
GdkGC *gc = gdk_gc_new (widget->window);
/* On commence par afficher l'image de fond qui est MainPixbuf de data. */
gdk_draw_pixbuf(widget->window, gc, data->MainPixbuf, 0, 0, 0, 0,
gdk_pixbuf_get_width(data->MainPixbuf),
gdk_pixbuf_get_height(data->MainPixbuf),
GDK_RGB_DITHER_MAX, 0, 0);
/* On ajoute maintenant par dessus la deuxième image à sa nouvelle position.
*/
gdk_draw_pixbuf(widget->window, gc, data->SecondPixbuf, 0, 0,
data->XCurrentPosition, data->YCurrentPosition,
gdk_pixbuf_get_width(data->SecondPixbuf),
gdk_pixbuf_get_height(data->SecondPixbuf),
GDK_RGB_DITHER_MAX, 0, 0);
/* Destruction du contexte graphique devenu inutile. */
g_object_unref (gc);
return FALSE;
}
/* Fonction de gestion du déplacement de la souris.*/
gboolean callback_mouse_moved (GtkWidget *drawingarea, GdkEventMotion *event,
MainData *data)
{
gint XOffset, YOffset; // Contiendra le décalage à effectuer.
/* On commence par voir si le bouton gauche de la souris est enfoncé.
* Pour ca on regarde la variable "states" de l'event transmis au callback.
*/
if (event->state>>8)
{
/* Si le bouton de la gauche de la souris est enfoncé et que le curseur
* est dans le carré noir alors on le déplace. */
if (data->ButtonPressedInPixbuf)
{
/* On calcule le décalage. */
XOffset = (gint)event->x - data->XPointer;
YOffset = (gint)event->y - data->YPointer;
data->XPointer = (gint)event->x;
data->YPointer = (gint)event->y;
/* Déplace le carré noir. */
data->XCurrentPosition += XOffset;
data->YCurrentPosition += YOffset;
/* Il ne nous reste plus qu'à demander à rafraichir la fenêtre.
* Pour se faire on simplement quelle partie il faut redessiner. Je
* spécifie ici l'ancienne position du rectangle qui sera redessiné
* en blanc.
*/
gtk_widget_queue_draw_area(drawingarea,
data->XCurrentPosition - XOffset,
data->YCurrentPosition - YOffset,
gdk_pixbuf_get_width(data->SecondPixbuf),
gdk_pixbuf_get_height(data->SecondPixbuf));
}
else
g_print("pas dans le carré \n");
}
return FALSE;
}
/* Fonction de gestion du clic de souris. */
gboolean callback_button_pressed (GtkWidget *widget, GdkEventButton *event,
MainData *data)
{
GdkRectangle zone; // permet de savoir si on est dans le rectangle.
GdkRegion *region = NULL;
/* On commence par voir si le bouton gauche de la souris est enfoncé.
*/
if (event->button == 1)
{
/* La deuxième étape maintenant doit nous assurer que le pointeur est
* bien sur le carré noir à déplacr.
*/
zone.x=data->XCurrentPosition;
zone.y=data->YCurrentPosition;
zone.width = gdk_pixbuf_get_width(data->SecondPixbuf);
zone.height = gdk_pixbuf_get_height(data->SecondPixbuf);
region = gdk_region_rectangle (&zone);
if (gdk_region_point_in(region, (gint)event->x,(gint)event->y))
{
data->ButtonPressedInPixbuf=TRUE;
data->XPointer = (gint)event->x;
data->YPointer = (gint)event->y;
}
else
data->ButtonPressedInPixbuf=FALSE;
gdk_region_destroy (region);
}
return FALSE;
}
gint main (gint argc, gchar *argv[])
{
GtkWidget *window = NULL;
GtkWidget *drawingarea= NULL;
MainData data;
gtk_init (&argc, &argv);
/* Création de la fenêtre principale. Rien de bien compliqué ici. */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size (GTK_WINDOW(window), 400, 400);
/* On crée deux images. L'image de fond est blanche et l'image déplacé est
* un cube noir de 40 de côté. Il est bien sûr possible d'utiliser
* la fonction gdk_pixbuf_new_from_file(); à la place.
*/
data.MainPixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, 400, 400);
gdk_pixbuf_fill(data.MainPixbuf, 0xFFFFFFFF);
data.SecondPixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, 40, 40);
gdk_pixbuf_fill(data.SecondPixbuf, 0x00000000);
/* On positionne la deuxième image au centre de la fenêtre. */
data.XCurrentPosition = 180;
data.YCurrentPosition = 180;
/* On initialise le reste des données. */
data.ButtonPressedInPixbuf = FALSE;
/* Création d'un GtkWidgetArea qui va nous servir de support. On y déposera
* par la suite une image de fond sur laquelle se déplacera une autre image
* à l'aide de la souris.
*/
drawingarea = gtk_drawing_area_new();
gtk_container_add(GTK_CONTAINER(window), drawingarea);
/* Maintenant un GtkDrawingArea n'écoute pas tous les signaux émis. Si tel
* était le cas il ralentirait lourdement l'application. En partant de là
* il nous faut lui indiquer quels signaux écoutés.
* GDK_POINTER_MOTION_MASK : est émis lorsque la souris se déplace sur le
* drawingarea
* GDK_BUTTON_PRESS_MASK : est émis lorsqu'un bouton de la souris est
* enfoncé
*/
gtk_widget_set_events(drawingarea, GDK_POINTER_MOTION_MASK|GDK_BUTTON_PRESS_MASK);
/* Enfin on connecte le signal écouté à une fonction CallBack. C'est dans
* ces fonctions que le calcul de déplacement s'effectuera.
*/
g_signal_connect (G_OBJECT(drawingarea), "motion-notify-event", G_CALLBACK(callback_mouse_moved), &data);
g_signal_connect (G_OBJECT(drawingarea), "button-press-event", G_CALLBACK(callback_button_pressed), &data);
g_signal_connect (G_OBJECT(drawingarea), "expose_event", G_CALLBACK(callback_expose_event), &data);
/* On connecte la fermeture de la fenêtre principale à l'arrêt du programme.
*/
g_signal_connect (window, "delete-event", G_CALLBACK(gtk_main_quit), NULL);
/* On affiche le tout */
gtk_widget_show_all (window);
/* On lance la boucle principale gtk. */
gtk_main ();
return 0;
}
J'espaire que vous acsépterai de m'édai encore une fois car a mon tour j'espaire édai des enfants dyslexiques.
Si j'ai besoin de faire un disque qui tourne c'est par se que dessus j'écriré un d qui se trensformera en p suivent la position du disque.
J'ai peut être des gros problème de compréhension mais je suis plus créatif que compréhensif.
Vu que c'est mon code je vais voir ce que je peux faire pour toi.
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
Voila le code modifié pour n'utiliser plus que les fonctions de cairo. Bonne lecture...
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174 #include <gtk/gtk.h> /* Définition de la taille du carré à déplacer. */ #define RectWidth 40 #define RectHeight 40 /* Structure qui va nous servir à atteindre la position de l'image * courante déplacée. */ typedef struct { gint XCurrentPosition; // Position X courante du carré gint YCurrentPosition; // Position Y courante du carré gint XPointer; // Position x de la souris lors du clic gint YPointer; // Position y de la souris lors du clic. gboolean ButtonPressedInPixbuf; } MainData; /* Fonction d'affichage du drawingarea. */ gboolean callback_expose_event(GtkWidget *widget, GdkEventExpose *event, MainData *data) { /* On récupère le cairo_context du GtkDrawingArea */ cairo_t *context = gdk_cairo_create (widget->window); /* On sélectionne la couleur blanche. */ cairo_set_source_rgb (context, 1, 1, 1); /* On met à jour l'affichage */ cairo_paint (context); /* On dessine un rectangle de 40 de côté à la position courante. */ cairo_rectangle (context, data->XCurrentPosition,data->YCurrentPosition, RectWidth, RectHeight); /* On change la couleur pour la noire. */ cairo_set_source_rgb (context, 0, 0, 0); /* On rempli le rectangle avec la couleur sélectionnée */ cairo_fill (context); /* On détruit le cairo_context devenu inutile. */ cairo_destroy(context); return FALSE; } /* Fonction de gestion du déplacement de la souris.*/ gboolean callback_mouse_moved (GtkWidget *drawingarea, GdkEventMotion *event, MainData *data) { gint XOffset, YOffset; // Contiendra le décalage à effectuer. /* On commence par voir si le bouton gauche de la souris est enfoncé. * Pour ca on regarde la variable "states" de l'event transmis au callback. */ if (event->state>>8) { /* Si le bouton de la gauche de la souris est enfoncé et que le curseur * est dans le carré noir alors on le déplace. */ if (data->ButtonPressedInPixbuf) { /* On calcule le décalage. */ XOffset = (gint)event->x - data->XPointer; YOffset = (gint)event->y - data->YPointer; data->XPointer = (gint)event->x; data->YPointer = (gint)event->y; /* Déplace le carré noir. */ data->XCurrentPosition += XOffset; data->YCurrentPosition += YOffset; /* Il ne nous reste plus qu'à demander à rafraichir la fenêtre. * Pour se faire on simplement quelle partie il faut redessiner. Je * spécifie ici l'ancienne position du rectangle qui sera redessiné * en blanc. */ callback_expose_event(drawingarea, NULL, data); } else g_print("pas dans le carré \n"); } return FALSE; } /* Fonction de gestion du clic de souris. */ gboolean callback_button_pressed (GtkWidget *widget, GdkEventButton *event, MainData *data) { GdkRectangle zone; // permet de savoir si on est dans le rectangle. GdkRegion *region = NULL; /* On commence par voir si le bouton gauche de la souris est enfoncé. */ if (event->button == 1) { /* La deuxième étape maintenant doit nous assurer que le pointeur est * bien sur le carré noir à déplacr. */ zone.x=data->XCurrentPosition; zone.y=data->YCurrentPosition; zone.width = RectWidth; zone.height = RectHeight; region = gdk_region_rectangle (&zone); if (gdk_region_point_in(region, (gint)event->x,(gint)event->y)) { data->ButtonPressedInPixbuf=TRUE; data->XPointer = (gint)event->x; data->YPointer = (gint)event->y; } else data->ButtonPressedInPixbuf=FALSE; gdk_region_destroy (region); } return FALSE; } gint main (gint argc, gchar *argv[]) { GtkWidget *window = NULL; GtkWidget *drawingarea= NULL; MainData data; gtk_init (&argc, &argv); /* Création de la fenêtre principale. Rien de bien compliqué ici. */ window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size (GTK_WINDOW(window), 400, 400); /* On initialise la position du carré au centre de la fenêtre. */ data.XCurrentPosition = 180; data.YCurrentPosition = 180; /* On initialise le reste des données. */ data.ButtonPressedInPixbuf = FALSE; /* Création d'un GtkWidgetArea qui va nous servir de support. On y déposera * par la suite une image de fond sur laquelle se déplacera une autre image * à l'aide de la souris. */ drawingarea = gtk_drawing_area_new(); gtk_container_add(GTK_CONTAINER(window), drawingarea); /* Maintenant un GtkDrawingArea n'écoute pas tous les signaux émis. Si tel * était le cas il ralentirait lourdement l'application. En partant de là * il nous faut lui indiquer quels signaux écoutés. * GDK_POINTER_MOTION_MASK : est émis lorsque la souris se déplace sur le * drawingarea * GDK_BUTTON_PRESS_MASK : est émis lorsqu'un bouton de la souris est * enfoncé */ gtk_widget_set_events(drawingarea, GDK_POINTER_MOTION_MASK|GDK_BUTTON_PRESS_MASK); /* Enfin on connecte le signal écouté à une fonction CallBack. C'est dans * ces fonctions que le calcul de déplacement s'effectuera. */ g_signal_connect (G_OBJECT(drawingarea), "motion-notify-event", G_CALLBACK(callback_mouse_moved), &data); g_signal_connect (G_OBJECT(drawingarea), "button-press-event", G_CALLBACK(callback_button_pressed), &data); g_signal_connect (G_OBJECT(drawingarea), "expose_event", G_CALLBACK(callback_expose_event), &data); /* On connecte la fermeture de la fenêtre principale à l'arrêt du programme. */ g_signal_connect (window, "delete-event", G_CALLBACK(gtk_main_quit), NULL); /* On affiche le tout */ gtk_widget_show_all (window); /* On lance la boucle principale gtk. */ gtk_main (); 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
Je vient de tester le code mais il ne marche pas quant je clique sur le carré rien ne bouge.
A par sa bien que sache a quoi sa saire j'ai pas tros compris cette partit du code: event->state>>8 on dirai une sous structure
Est pour t'a structure MainData pour y accédé tu écrit juste data alors qu'il est écrit Maindata, normalement sa aurai du être MainData.XCurrentPosition = 180;
C'est la syntaxe en C pour un décalage de bits.
En gros, il décale de 8 bits vers la droite la valeur de event->state.
Bon, en fait ce qu'il a écrit ne fonctionne pas, car il suffit que n'importe lequel des bits après le 8ème soit positionné à 1 pour qu'on pense que le bouton gauche de la souris soit appuyé...
If faudrait en fait au minimum écrire pour être sûr de tester l'état du bouton gauche de la souris:
Et même comme cela ce n'est pas encore parfait, car les combinaisons de click bouton gauche + touches Ctrl, Shift ou Super agissent comme si elles n'étaient pas pressées.
Code : Sélectionner tout - Visualiser dans une fenêtre à part if (event->state & GDK_BUTTON1_MASK)
Non non, là c'était correct, pour une affectation, il faut utiliser le nom de la variable (data), pas celui du type (MainData).
Pour la structure MainData c'est bon j'ai compris, j'ai toujour eu du mal avec les structure mais maintenant je me force à en utiliser comme sa petit a petit sa va rentrée.
Pour le reste je regarderai quant j'aurrai la tête reposé car les opérateurs de décalage bit je m'en souvient plus
Je suis très étonné que cela ne marche pas. Chez moi je déplace le petit carré noir sans problème!![]()
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
ça marche, mais c'est buggé !
Tu ne testes pas que le bit 8 est à 1, tu testes si au moins un des bits de poids >= 8 est à 1. Cela signifie que si tu auras le même comportement qu'un clic gauche si tu:
- cliques avec n'importe quel bouton de la souris
- appuies sur les touches spéciales super/hyper/meta (super correspond à la touche Windows, pour les autres je ne sais pas)
Il faudrait sans doute filtrer avec GDK_MODIFIER_MASK.
Je suis d'accord avec toi sur la détection de la souris. J'ai fais un poil rapide là dessus.
Mais grex1 dit qu'il n'arrive pas à déplacer le carré, d'où ma remarque.![]()
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
C'est bizarre quant je clique sur le carré rien ne bouge, par contre quant je clique sur la croix pour fermer le programme 1 seconde juste avent que sa se ferme je voix le carré qui bouge
Oui c'est bizarre, comme s'il n'y avait pas de mise à jour de l'affichage à chaque déplacement. L'appui sur la fermeture produirai cette mise à jour juste avant destruction.
Quelle distribution utilises-tu et quelle version de Gtk+/ Cairo est installée?
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