[C++][QT] Récupérer le X et Y de la souris

Récupérer le X et Y de la souris [C++][QT] - C++ - Programmation

Marsh Posté le 26-02-2007 à 19:12:34    

Bonjour à tous :hello:
 
Je cherche un coup de main pour modifier un logiciel dont j'ai les codes sources. Il s'agit du logiciel MAPANNOT (http://perso.orange.fr/mapannot/#french)
Il permet de charger une carte au format jpeg, et travailler dessus :
- Faire des tracés géometriques
- Mesurer des distances
- Etc...
 
Il possède une fonction de zoom, qui fonctionne avec la molette de la souris. En interne, au demarrage, le logiciel charge la carte, et construit plusieurs images en divisant a chaque fois la taille par 2, de facon a avoir plusieurs image en fonction du niveau de zoom selectionné.
 
A chaque fois qu'on change de niveau de zoom, le logiciel affiche l'image correspondante a ce niveau de zoom. Ca fonctionne tres bien, mais le souci, c'est que je voudrais que lorsque je vise un point de la carte avec la souris, par exemple Paris, et que je zoome (ou que je dezoome), Paris reste sous le curseur. Car sinon c'est chiant, a chaque fois il faut bouger les ascenseurs verticaux et horizontaux pour retrouver la ville sur laquelle on a zoomé ou dézoomé.
 
Le logiciel est ecrit en C++ et utilise la bibliothèque graphique QT, version 3.
 
J'ai reperé dans le source la fonction qui est appelée lorsque la molette est activée, et qui charge la bonne image en fonction du niveau de zoom. A la suite de ça il ne me resterait plus qu'a deplacer l'image pour que la ville qui etait pointée se retrouve a nouveau sous le curseur. Mais pour cela je dois récuperer l'emplacement X et Y du curseur de la souris, PAR RAPPORT AU CADRE dans lequel la carte est affichée.
 
En editant le fichier 'qevent.h', je vois qu'il existe des methodes que je peux appeler lorsque j'ai récupéré l'evenement de la molette :
int    x()          const   { return p.x(); }
int    y()          const   { return p.y(); }
int    globalX()    const   { return g.x(); }
int    globalY()    const   { return g.y(); }
 
Le souci c'est que les 2 premieres me retourne le X et Y de la souris, mais par rapport AU CONTENU du cadre. Et les 2 dernieres me donnent le X et Y de la souris, mais par rapport a l'ecran :(
 
Ou pourrais-je récuperer le X et Y de la souris mais par rapport au cadre qui contient l'image ?
 
Merci pour votre aide eventuelle.

Reply

Marsh Posté le 26-02-2007 à 19:12:34   

Reply

Marsh Posté le 26-02-2007 à 19:20:33    

Salut,
Je comprends pas en quoi x() et y() ne te conviennent pas :/
Quelle différence fais-tu entre des coordonnées dans le contenu du cadre et celle dans le cadre??

Reply

Marsh Posté le 26-02-2007 à 19:32:55    

Et bien par exemple la carte que j'utilise fait environ 6000 pixel par 6000 pixel, donc j'ai des ascenseurs pour 'scroller' l'image. Et si mon curseur est positionné tout en bas a droite de l'image, et que je donne un coup de dézoom, le x() et x() me renvoie 6000 et 6000.
 
Ces 2 valeurs j'en ai effectivement besoin, pour savoir quelle ville de la carte etait pointée, mais j'ai egalement besoin du X et Y par rapport au cadre (qui ressemblerait plutot a un truc du genre 1000, 680), pour décaler l'image une fois dezoomé, et refaire pointer la ville (maintenant a 3000, 3000, a cause du dézoom par 2) sur la position 1000, 680 de la souris.
 
Je sais pas si c'est tres clair !? :)

Reply

Marsh Posté le 26-02-2007 à 19:43:31    

Ah, ok; donc si je comprends bien, l'image est affichée dans une QScrollView? (Je vois pas comment le point peut-être différent du point d'affichage sinon)
Si c'est le cas, regardes du côté de QScrollView::contentsToViewport. Si je me trompe pas de sens, c'est ce que tu veux ;)
 
Si c'est pas un QScrollView, la carte est affichée avec quel widget?

Reply

Marsh Posté le 26-02-2007 à 19:46:18    

Exact, le 'conteneur' de la carte est bien un QScrollView !
 
Je regarde de suite a quoi correspond le QScrollView::contentsToViewport.
 

Reply

Marsh Posté le 26-02-2007 à 20:34:50    

Bon ca renvoie bien ce dont j'ai besoin !! Merci pour ton aide.
 
Par contre j'ai constaté un truc bizarre :
 
Le prototype de la fonction c'est contentsToViewport ( int x, int y, int & vx, int & vy )
 
J'ai donc voulu faire :
 
int x, y;
 
contentsToViewport ( scrollViewObject->x(), scrollViewObject->y(), &x, &y );
 
Mais ca ne marche pas !! Je suis obligé de faire contentsToViewport ( scrollViewObject->x(), scrollViewObject->y(), x, y ) pour que ca compile et que ca marche. Y a plus besoin de passer l'adresse de x et y en C++ !??? C'est quoi ce bordel !? :D

Reply

Marsh Posté le 26-02-2007 à 20:45:43    

Si tu regardes de plus près le prototype, tu vois qu'il prend des références vers x et y, pas des pointeurs ;)

Reply

Marsh Posté le 26-02-2007 à 22:00:49    

ben je vois int & vx et int & vy
 
Comme la fonction modifie des variables que je lui envoie, et que j'ai l'habitude du C je voulais lui envoyer &x et &y.
 
En clair en C++ si je fais :
 
void swap ( int & a, int & b )
{
 // Inversion de a et de b
}
 
int main ( void )
{
 int x = 10, y = 20;
 
 swap( x, y );
}
 
cela va t-il marcher ? A la fin x vaudra 20 et y vaudra 10 ?
Et dans la fonction swap quel serait le code ?
 
int temp = a;
b = a;
b = temp;
 
ou bien
 
int temp = *a;
*b = *a;
*b = temp;
 
?

Reply

Marsh Posté le 26-02-2007 à 22:12:56    

Bien sur que ça marche, pour reprendre ton exemple, ça donnerait:

Code :
  1. void swapByRef(int &a, int &b)
  2. {
  3.    int tmp = a;
  4.    a = b;
  5.    b = tmp;
  6. }
  7. void swapByPtr(int *a, int *b)
  8. {
  9.    int tmp = *a;
  10.    *a = *b;
  11.    *b = tmp;
  12. }
  13. int main(int argc, char **argv)
  14. {
  15.    int a = 1;
  16.    int b = 2;
  17.    swapByRef(a, b);
  18.    // maintenant a==2 et b==1
  19.    swapByPtr(&a, &b);
  20.    // et maintenant, on revient aux valeurs initiales
  21.    return 0;
  22. }


 
En gros, l'expression &a contient l'adresse de a, du coup, si tu passes 'a' une fonction qui attend &a, elle va recevoir l'adresse de a, et non une copie de sa valeur.

Reply

Marsh Posté le 27-02-2007 à 01:35:12    

Si je comprends bien les nouveaux languages tendent a faire disparaitre les pointeurs ou quoi !?? Je trouve que c'est bien plus simple a comprendre avec des pointeurs pourtant. Au moins on sait exactement ce qu'il se passe au niveau de la compilation et de l'execution du code, mais bon...

 

Sinon ouf, je viens de reussir à implémenter la fonctionnalité que je désirais. J'aurais mis le temps mais ca finalement ca marche ! Là je peux naviguer sur la carte uniquement avec la molette du zoom en visant le point qui m'interesse, plus besoin d'utiliser ces putains d'ascenseur a chaque fois !!! :)

 

Bon maintenant je voudrais implémenter une autre fonction....
Je voudrais pouvoir "agripper" la carte et la deplacer, afin de naviguer dessus a ma guise, toujours sans utiliser les barres d'ascenseurs.

 

Exactement comme font les cartographies en ligne (mappy, viamichelin, etc...) en fait on agrippe la carte en appuyant sur le bouton gauche de la souris, on deplace le curseur ce qui a pour effet de bouger la carte, et ensuite on relache le bouton de la souris.

 

Comment pourrais-je réussir à faire ça ?

 

Il faut que je rajoute un evenement souris ou un truc comme ca ?


Message édité par nlc le 27-02-2007 à 01:56:56
Reply

Marsh Posté le 27-02-2007 à 01:35:12   

Reply

Marsh Posté le 27-02-2007 à 15:24:17    

Oui, les "nouveaux" langages (et pas qu'eux) tendent à cacher cette notion de pointeurs si j'ai bien compris. Mais C++ n'en fait pas parti, et le passage de variables par référence est une méthode comme une autre (mais je ne peux honnêtement pas t'expliquer quelle est la raison pour préférer telle méthode ou telle autre :().
 
Pour ta nouvelle fonctionnalité, il faut que tu réimplémentes mouseMoveEvent(). Si le tracking de la souris n'est pas activé pour ce widget, cet événement n'est généré que lorsqu'un bouton est pressé en même temps que la souris est déplacée, ce qui correspondrais à ce que tu veux :)

Reply

Marsh Posté le 27-02-2007 à 15:29:07    

Oui c'est exactement ca qu'il me faut !
 
Je vais étudier ça en détail et essayer de l'implémenter.
 
Merci pour ton aide

Reply

Marsh Posté le 27-02-2007 à 19:49:47    

Quel idiot, avec un brin de jugeotte, j'aurais pu y penser (à pourquoi utiliser des références plutôt que des pointeurs)...
Tu trouveras la raison sur la FAQ C++ lite si tu cherches pourquoi ;)

Reply

Marsh Posté le 27-02-2007 à 19:54:18    

J'ai pas tout capté mais comme j'y connais rien en C++ c'est peut être pour ça !

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed