Results 1 to 7 of 7

Thread: mouse pos() returns wrong position

  1. #1
    Join Date
    Sep 2019
    Posts
    16
    Thanks
    5
    Qt products
    Qt5
    Platforms
    Windows

    Question mouse pos() returns wrong position

    Hello !,
    So i have a problem getting pos from the point where i click on the mouse ( using right click )
    check this video :
    https://streamable.com/cjo0d
    - Here you can see at the beginning i try moving him around using right click on the mouse and it's all working fine. But when i reach the land or at least when im near it the returned position is completely different as i expected it to be...
    you can see when i print the character current position and the positioning of the mouse ( when i press right click ) in the debug console it gives me wrong coordinates ( from the mouse ) and i don't know why... Sea and Land are two different QGraphicsPixmapItems both have their own class, so maybe it has to do something with that ?
    Here is the main class code:

    Game.h:

    Qt Code:
    1. #ifndef GAME_H
    2. #define GAME_H
    3. #include "player.h"
    4. #include "button.h"
    5. #include "sea.h"
    6. #include "land.h"
    7.  
    8. #include <QGraphicsView>
    9. #include <QGraphicsScene>
    10. #include <QObject>
    11. #include <QMouseEvent>
    12. #include <QGraphicsSceneMouseEvent>
    13. #include <QGraphicsScene>
    14. #include <QWidget>
    15. #include <QKeyEvent>
    16.  
    17. class Game: public QGraphicsView{
    18. Q_OBJECT
    19. public:
    20. // this class stuff
    21. static QString in_room;
    22. Game(QWidget *parent=NULL);
    23. void menu();
    24. void createMap();
    25. void createPlayer();
    26. QPixmap darkenImage(QString image, float num);
    27.  
    28. // other class stuff
    29. Player *player;
    30. Button *startButton;
    31. Button *quitButton;
    32. Land *land;
    33. Sea *sea;
    34.  
    35. // static stuff
    36. int curr_pos_in_menu;
    37. void changeColorOfButton();
    38.  
    39. public slots:
    40. void start();
    41. void mousePressEvent(QMouseEvent *event);
    42. };
    43.  
    44. #endif // GAME_H
    To copy to clipboard, switch view to plain text mode 

    Game.cpp:

    Qt Code:
    1. #include "game.h"
    2. #include "player.h"
    3. #include "button.h"
    4.  
    5. #include <QGraphicsRectItem>
    6. #include <QGraphicsScene>
    7. #include <QDebug>
    8. #include <QApplication>
    9. #include <QTimer>
    10. #include <QFont>
    11. #include <QMessageBox>
    12. #include <fstream>
    13. #include <cmath>
    14. #include <QRect>
    15. #include <QDesktopWidget>
    16. #include <QtMath>
    17.  
    18. QString Game::in_room = "menu";
    19.  
    20. Game::Game(QWidget *parent)
    21. {
    22. scene = new QGraphicsScene();
    23. scene->setSceneRect(0,0,350,300);
    24. setFixedSize(350,300);
    25. setScene(scene);
    26. setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    27. setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    28. setBackgroundBrush(QBrush(QImage("red")));
    29. show();
    30. menu();
    31. }
    32.  
    33. void Game::menu()
    34. {
    35. QGraphicsTextItem *title = new QGraphicsTextItem("NIGHTLESS");
    36. title->setPos(10,30);
    37. title->setFont(QFont("comic sans",40,70));
    38. scene->addItem(title);
    39.  
    40. qDebug() << width();
    41. startButton = new Button("START", 200, 50);
    42. startButton->setPos(width()/2-startButton->rect().width()/2,125);
    43. connect(startButton,SIGNAL(clicked()),this,SLOT(start()));
    44. scene->addItem(startButton);
    45.  
    46. quitButton = new Button("QUIT", 200, 50);
    47. quitButton->setPos(width()/2-quitButton->rect().width()/2,200);
    48. connect(quitButton,SIGNAL(clicked()),this,SLOT(close()));
    49. scene->addItem(quitButton);
    50.  
    51. }
    52.  
    53. void Game::createMap()
    54. {
    55. land = new Land;
    56. land->setPos(0,0);
    57. scene->addItem(land);
    58.  
    59. sea = new Sea;
    60. sea->setPos(0,0);
    61. scene->addItem(sea);
    62. }
    63.  
    64. void Game::createPlayer()
    65. {
    66. player = new Player;
    67. player->setFlag(QGraphicsItem::ItemIsFocusable);
    68. player->setFocus();
    69. centerOn(player);
    70. scene->addItem(player);
    71. }
    72.  
    73. QPixmap Game::darkenImage(QString file_name, float num)
    74. {
    75. QImage tmp( file_name );
    76.  
    77. for(int i=0;i<tmp.height();i++)
    78. {
    79. for(int k=0;k<tmp.width();k++)
    80. {
    81. QColor color( tmp.pixel( k, i ) ); // changed this from pixelColor() to ensure alpha is copied
    82. if ( tmp.pixel(k,i) != 0) // modify only the pixels with non-zero alpha
    83. {
    84. color.setRgb(color.red()*num,color.blue()*num,color.green()*num);
    85. tmp.setPixelColor(k,i,color);
    86. }
    87. }
    88. }
    89.  
    90. // Now, convert the image to a pixmap and set it on the graphics object
    91. QPixmap t = QPixmap::fromImage( tmp );
    92. return t;
    93. }
    94.  
    95. void Game::start()
    96. {
    97. scene->clear();
    98. in_room = "world";
    99. // semi-transparent background
    100. /*
    101.   QRect rec = QApplication::desktop()->screenGeometry();
    102.   int height = rec.height();
    103.   int width = rec.width();
    104.   */
    105.  
    106. setSceneRect(0,0,7097,7298);
    107. setFixedSize(1000,800);
    108. //setBackgroundBrush(QBrush(QImage(":/Images/Grass.png")));
    109. //showFullScreen();
    110.  
    111. createMap();
    112. createPlayer();
    113. }
    114.  
    115. void Game::mousePressEvent(QMouseEvent *event)
    116. {
    117. if(event->buttons() == Qt::RightButton && in_room!="menu"){
    118.  
    119. QLineF ln(event->pos(),player->pos());
    120. int angle = -1 * ln.angle() + 460;
    121.  
    122. int tmp = angle + 80;
    123. if(tmp>360)
    124. tmp-=360;
    125.  
    126. if(angle > 360)
    127. angle += -360;
    128.  
    129. player->setPlayerRotation(angle,tmp);
    130.  
    131. QPointF t(event->pos());
    132. player->setDestination(event->pos());
    133.  
    134. }
    135. }
    To copy to clipboard, switch view to plain text mode 

    In the Land and Sea class i just setPixmap to the image, put them into the scene,set position and that is it.

    And i have one more question, how do i make a player stop when he reaches his destination ? i was thinking about making an QGraphicsRectItem whenever i press a right button and then checking if player has collided with that item and when he does he stops and then that item gets deleted or is there a better and easier way to do that, cause comparing mouse pos() and player pos() is not working.

    Any kind of help or advice is appreciated !!!
    Last edited by FlyDoodle; 30th September 2019 at 15:13. Reason: spelling corrections

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,172
    Thanks
    235
    Thanked 662 Times in 652 Posts
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: mouse pos() returns wrong position

    Where is this "mousePressedEvent()" slot being called from? Or have you mistakenly defined an event handler as a slot when it should be a protected member function?

    The player's position will always be in coordinates relative to its QGraphicsItem parent's upper left corner. If it has no parent (i.e. it has been added as a top-level item in a scene), then its position will be relative to the top left corner of the scene, in scene coordinates. If you are handling a mouse press event as an override to a QWidget event (in other words, the QGraphicsView), then the coordinates here will be in widget (pixel) coordinates relative to the top left corner of the widget.

    I don't know what your Land and Sea class (or classes) is, but if they are also QGraphicsItem instances in the scene, then mouse press events on them will be relative to their top-left corners.

    So you are trying to compare coordinates that are all relative to something different. Your video makes this obvious - as soon as you click on the land, the player turns towards the top left of the view, because you have clicked on the top left corner of the land, and the relative coordinate returned from that click is close to (0,0). You need to convert all coordinates so they refer to a common origin, maybe using QGraphicsItem::mapToScene() and QGraphicsView::mapToScene().
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. #3
    Join Date
    Sep 2019
    Posts
    16
    Thanks
    5
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: mouse pos() returns wrong position

    Hello
    thank you for answering, and regarding the mousePressEvent(), its being called in the game class:
    This is the code :

    Qt Code:
    1. void Game::mousePressEvent(QMouseEvent *event)
    2. {
    3. if(event->buttons() == Qt::RightButton && in_room!="menu"){
    4.  
    5. QLineF ln(event->pos(),player->pos());
    6. int angle = -1 * ln.angle() + 460;
    7.  
    8. int tmp = angle + 80;
    9. if(tmp>360)
    10. tmp-=360;
    11.  
    12. if(angle > 360)
    13. angle += -360;
    14.  
    15. player->setPlayerRotation(angle,tmp);
    16.  
    17. QPointF t(event->pos());
    18. player->setDestination(t);
    19.  
    20. }
    21. }
    To copy to clipboard, switch view to plain text mode 

    I tried putting :
    Qt Code:
    1. QPointF t(mapToScene(event->pos()));
    To copy to clipboard, switch view to plain text mode 

    But it still doesn't work...

    And yeah they are both QGraphicsItem instances in the scene, here is the code if helps :
    Land and Water files ( both are the same just the namings are different )
    Qt Code:
    1. #ifndef LAND_H
    2. #define LAND_H
    3.  
    4. #include <QObject>
    5. #include <QGraphicsPixmapItem>
    6.  
    7. class Land: public QObject, public QGraphicsPixmapItem{
    8. Q_OBJECT
    9. public:
    10. Land(QGraphicsPixmapItem *parent=NULL);
    11.  
    12. private:
    13. QString file_name;
    14. };
    15.  
    16. #endif // LAND_H
    To copy to clipboard, switch view to plain text mode 
    .cpp
    Qt Code:
    1. #include "land.h"
    2.  
    3. Land::Land(QGraphicsPixmapItem *parent)
    4. {
    5. file_name = ":/Images/Land.png";
    6. setPixmap(QPixmap(file_name));
    7. }
    To copy to clipboard, switch view to plain text mode 

    I don't know how to make my mouse event ignore those two classes when pressing right click on them ( so that its like i'm trying to access scene only and get coordinate from it )... I tried looking for the solution on google ( ignore() functions and so on ) and i still have no idea...

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,172
    Thanks
    235
    Thanked 662 Times in 652 Posts
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: mouse pos() returns wrong position

    mousePressEvent(), its being called in the game class
    No, it isn't being called there, it is defined there. It is probably being called from Qt's event loop, handling events on the QGraphicsView that are not being handled by other objects.

    You should read the Qt documentation on the Qt Graphics View Framework and pay particular attention to the section on "The Graphics View Coordinate System".

    You should also be sure that you are handling your mouse events correctly. There is a complete set of mouse and other events that are handled internally in the QGraphicsScene class. These take care of mapping events in the scene to the graphical objects that have the current focus or are under the mouse. If you are handling mouse events at both the widget level (QGraphicsView) and scene level, then the coordinate systems are not the same.

    My advice is to handle mouse events only at the scene level (by implementing handlers for your QGraphicsItem-based classes), and map everything to scene coordinates.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. #5
    Join Date
    Sep 2019
    Posts
    16
    Thanks
    5
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: mouse pos() returns wrong position

    No, it isn't being called there, it is defined there.
    oh i see, ye i have to take a look at view, scene and events handling stuff a little bit more, tho after trying some stuff out i realized that when i was creating a line between the player and the mouse i forgot to use mapToScene when initializing points. So far it seems to be working. Thank you very much for that !!

    Tho i have one more question, how do i put waves (image) around my island in the game as the background. I want to make it so that for example 60 x 60 pixels waves fill the background. Doing setBackgroundBrush(QBrush(QImage("path"))); will set the background the way i want it to, but the problem is when the player is moving and he gets near the water, he has to stop. I wanted to check if he is near the water using collision. Like that class Land i made class Sea and this class is also QPixmapItem and i could just check if the player has collided with Sea but the problem comes when i want the sea to be moving, cause changing pictures takes time and that's not optimal...

  6. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,172
    Thanks
    235
    Thanked 662 Times in 652 Posts
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: mouse pos() returns wrong position

    cause changing pictures takes time and that's not optimal...
    Changing pictures only takes time if you are loading them from disk every time you change. If you keep the pictures in memory in the correct form (QPixmap), then changing the image is as fast as calling setPixmap(). QPixmap instances use data sharing, which means that calling setPixmap() does not involve a data copy of the pixmap, simply swapping an internal reference. There is even a QPixmapCache cache that you can store your pixmaps in.

    For detecting if your player has walked into the water, you might be able to use QPolygon to define the area of the land, and QPolygon::containsPoint() to determine if your player is still on land.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  7. The following user says thank you to d_stranz for this useful post:

    FlyDoodle (5th October 2019)

  8. #7
    Join Date
    Sep 2019
    Posts
    16
    Thanks
    5
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: mouse pos() returns wrong position

    I didn't put QPixmap on the heap, that is why it took couple of seconds to load an image every time. Thank you very much for the help !!!

Similar Threads

  1. view position of mouse position in GraphicsScene
    By Raghaw in forum Qt Programming
    Replies: 2
    Last Post: 23rd August 2012, 05:46
  2. QProcess.pid() returns wrong pid in PyQt(windows)
    By vertusd in forum Qt Programming
    Replies: 1
    Last Post: 16th April 2011, 08:57
  3. QHttp get returns the wrong page
    By SpeedxDevil in forum Newbie
    Replies: 1
    Last Post: 14th November 2010, 23:46
  4. mouseMoveEvent contains wrong position?
    By draftpunk in forum Qt Programming
    Replies: 10
    Last Post: 12th September 2008, 02:59
  5. Replies: 4
    Last Post: 27th July 2006, 12:13

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.