Salut tous le monde
La question est simple : comment puisse je detecter la position de la souris au dessus d'un widget ?
Merci
Version imprimable
Salut tous le monde
La question est simple : comment puisse je detecter la position de la souris au dessus d'un widget ?
Merci
Bonjour.
La souris génère différents types d'évènements sur un widget. Il te faut connecter le signal "motion-notify-event" du widget considéré à un callback du type gboolean user_function (GtkWidget *widget, GdkEvent *event, gpointer user_data);.
Maintenant, pour éviter de surcharger la boucle principale Gtk+, les concepteurs n'ont pas activé par défaut la lecture de cet évènement pour tous les widgets. Il te faut en plus le demander. Pour ca utilises la fonction void
gtk_widget_add_events (GtkWidget *widget, gint events);. events vaudra ici GDK_POINTER_MOTION_MASK.
je veux savoir la position de la souris juste quand je clique au dessus d'un widget quelconque.
je pense que cet evennement me donne la postion de la souris quand elle passe au dessus ! non ?
En plus, est ce que vous pouvez m'offrir un cours qui explique tout ça.
merci beaucoup
Effectivement l'explication que j'ai donné sert au passage de la souris et non lors d'un clic. Mais c'est la question qui était posée ;).
Pour connaître la position lors d'un clic il suffit de reprendre exactement le même principe en utilisant l'évènement GDK_BUTTON_PRESS_MASK en lieu et place du GDK_POINTER_MOTION_MASK.
Le prototype du callback associé est le suivant :
GdkEvent est une union. Tu peux donc le remplacer par la structure qui t'intéresse ici, c'est à dire par un GdkEventButton. Voila sa structure :Code:gboolean user_function (GtkWidget *widget, GdkEvent *event, gpointer user_data)
Tu récupéreras en x,y les coordonnées relatives de la souris dans le widget considéré.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13 struct GdkEventButton { GdkEventType type; GdkWindow *window; gint8 send_event; guint32 time; gdouble x; gdouble y; gdouble *axes; guint state; guint button; GdkDevice *device; gdouble x_root, y_root; };
Bonjours les GThacKtivist.
Bravo gérald3d et merci pour toute l'aide précise que tu nous apporte a tous,
comme l'a expliquer gérald3d tu doit faire un (cast) vers un pointeur d'une structure GdkEventButton:
---
Mais si tu veut uniquement capter les clic gérald3d s'est tromper car il ne savait pas que tu voulais récupérer la ou l'on clique
et du coup gérald3d ne t'a pas dit de changer de signal.
Il faut en conséquence utiliser le signal: "button-press-event".
La déclaration du callback (fonction de rappelle) est la même.
Sinon un example complet:Code:
1
2
3
4
5
6
7
8
9
10 gboolean on_mouse_clic(GtkWidget *widget, GdkEvent *event, gpointer user_data) { GdkEventButton *mouse_click = (GdkEventButton *) event ; fprintf(stdout,"Mouse clic detected at (%lf, %lf)\n", mouse_click->x, mouse_click->y) ; return FALSE ; // Signal handler continue processing. }
Voila a toi de jouer.Code:
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 /** Simple example How-To capture a mouse clic using gtk+-3.0. * * To compile with command-line: * * $ cc main.c `pkg-config --cflags --libs gtk+-3.0` * **/ #include <gtk/gtk.h> #include <stdlib.h> static void destroy(GtkWidget *widget ,gpointer pointer) ; static gboolean delete_event(GtkWidget *widget,GdkEvent *event,gpointer pointer) ; static gboolean on_mouse_clic(GtkWidget *widget, GdkEvent *event, gpointer user_data) ; int main(int argc, char *argv[]) { gtk_init(&argc, &argv) ; GtkWidget *window ; window = gtk_window_new(GTK_WINDOW_TOPLEVEL) ; gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK); gtk_window_maximize(GTK_WINDOW(window)) ; g_signal_connect_after(G_OBJECT(window), "delete-event", G_CALLBACK(delete_event), NULL) ; g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL) ; g_signal_connect(G_OBJECT(window), "button-press-event", G_CALLBACK(on_mouse_clic), NULL) ; gtk_widget_show_all(window) ; gtk_main() ; return 0 ; } static void destroy(GtkWidget *widget, gpointer pointer) { exit(EXIT_SUCCESS) ; } static gboolean delete_event(GtkWidget *widget,GdkEvent *event,gpointer pointer) { /** This function will call the destroy(...) function by returning FALSE * by continuing the signal loop. **/ return FALSE ; // Signal handler continue processing. } gboolean on_mouse_clic(GtkWidget *widget, GdkEvent *event, gpointer user_data) { GdkEventButton *mouse_click = (GdkEventButton *) event ; fprintf(stdout,"Mouse clic detected at (%lf, %lf)\n", mouse_click->x, mouse_click->y) ; return FALSE ; // Signal handler continue processing. }
Sinon il vaudrai mieux renvoyer TRUE pour le callback on_mouse_clic(...) car sinon la mainloop peut afficher 2 fois la position pour un seule clic.
Mais dans ce cas tu arrête pendant une itération le gestionnaire de signaux a ta fonction de rappelle sauf quelque(s) signaux qui sont obliger par Gtk-3.
P.S: Même si tout a été très bien expliquer par mon amis gérald3d je voulais montrer un example.
@Luke spywoker
Quelques remarques:
- pas besoin de connecter delete-event si tu ne comptes pas faire quelque chose quand l'utilisateur tente de fermer l'application (comme afficher une boite de dialogue de sauvegarde par exemple).
- appeler exit en réponse au signal destroy est un peu violent, en général on va plutôt quitter la boucle principale en appelant gtk_main_quit et faire un return 0 dans dans le main
Pour revenir sur le sujet initial, il me semble que certains widgets ne réagissent pas au clic et doivent être mis dans un GtkEventBox. Je crois que c'est le cas pour les GtkLabel.
Merci les gars mais je le savait, je ne l'ai simplement pas signaler a jamalkamal.Citation:
Pour revenir sur le sujet initial, il me semblent que certains widgets ne réagissent pas au clic et doivent être mis dans un GtkEventBox. Je crois que c'est le cas pour les GtkLabel.
De toute façon Gtk renferme de multiples secrets,
ce qui ne l'empêche pas d'être la meilleurs G.U.I pour GNU/Linux et les autres portage vers d'autres systèmes sont très bons.
De rien jamalkamal,
il faut maintenant cliquer sur le bouton résolus si tu a trouver réponse a ta question.
P.S: Un test du type de l'évènement est a ajouter à la fonction de rappelle, quand même.
Bonsoir à tous,
Par curiosité, jamalkamal, pourquoi as tu besoin de connaitre la position de la souris sur un widget quelconque dans ton application ?
Encore par curiosité, quelqu'un saurais comment Gtk Inspector s'y prend ?