Confusion with mouse coordinates
-
Hi folks and pros,
I am trying to understand geometry and mouse coordinates.
My final goal is to creat an application where you can place "annotations" to an image.
I have created a stripped down minimal example based on qt example QEnhancedgraphicsViewer (thanks for that).The issues I have:
-
The ToolTip shows up far from the mouse position.
See screenshot: http://code.ademmler.com/marker/screenshot01.png -
The marker position I get on macOSX and windows are differing
-
What is the best "pos" variant to get reproducible results.
I want to store (as file) and reload such markers.
You can download code here:
http://code.ademmler.com/marker/QtMarkerMinimal.zip -
-
Hi folks and pros,
I am trying to understand geometry and mouse coordinates.
My final goal is to creat an application where you can place "annotations" to an image.
I have created a stripped down minimal example based on qt example QEnhancedgraphicsViewer (thanks for that).The issues I have:
-
The ToolTip shows up far from the mouse position.
See screenshot: http://code.ademmler.com/marker/screenshot01.png -
The marker position I get on macOSX and windows are differing
-
What is the best "pos" variant to get reproducible results.
I want to store (as file) and reload such markers.
You can download code here:
http://code.ademmler.com/marker/QtMarkerMinimal.zip@ademmler said in Confusion with mouse coordinates:
The ToolTip shows up far from the mouse position.
See screenshot: http://code.ademmler.com/marker/screenshot01.pngIf you compare the offset of your clicked point with the annotation, you will set that it's about the same difference.
So there's probably a mapping issue...After checking your code... Indeed, there is....
The mouseEvent is in widget's coordinates, while you show theQToolTip
in global coordinates...void QEnhancedGraphicsView::mouseMoveEvent(QMouseEvent *event) { QString text; text = QString("%1 X %2").arg(event->pos().x()).arg(event->pos().y()); // Global coordinate-system, but widget coord. position // QToolTip::showText(event->pos(), text); // this should fix it QToolTip::showText(this->mapToGlobal(event->pos()), text); }
Edit:
Played around a little with your example and draged an image in to test the actual annotation function... currently the annoations appear not on the image where you actually click in your scene...
This will fix it.void QEnhancedGraphicsView::slotPaintMarker(QPoint pos, int num) { QString stream; QTextStream(&stream) << "Paint marker: #" << num << " " << pos.x() << " " << pos.y() << "\n"; emit signalAddText(stream); qDebug() << "Paint Marker " << stream; QPixmap pix(50, 50); QPainter *painter = new QPainter(&pix); painter->setPen(QColor(0, 0, 0, 255)); painter->setBrush(QColor(255, 255, 255, 255)); painter->drawRect(0, 0, 49, 49); painter->setPen(Qt::black); painter->setFont(QFont("Verdana", 21, QFont::ExtraBold)); painter->drawText(QRect(0, 0, 50, 50), Qt::AlignCenter, QString::number(num)); delete painter; QGraphicsPixmapItem *anotation = new QGraphicsPixmapItem; anotation->setPixmap(pix); // #### FIX ############## QPointF pos_ = this->mapToScene(pos); anotation->setPos(pos_.x(), pos_.y()); // ######################### anotation->acceptDrops(); anotation->setFlag(QGraphicsItem::ItemIsMovable); anotation->setData(100, true); anotation->setData(101, num); this->scene()->addItem(anotation); }
Then it just depends on what your coordinates really need to show... currently they are showing the scene coords. So the first pixel of the image will not have (0,0), therefore the annotation also wont, but they depend on your scroll factor of your scene... Maybe you need/want to fix it later.
-
-
@ademmler said in Confusion with mouse coordinates:
The ToolTip shows up far from the mouse position.
See screenshot: http://code.ademmler.com/marker/screenshot01.pngIf you compare the offset of your clicked point with the annotation, you will set that it's about the same difference.
So there's probably a mapping issue...After checking your code... Indeed, there is....
The mouseEvent is in widget's coordinates, while you show theQToolTip
in global coordinates...void QEnhancedGraphicsView::mouseMoveEvent(QMouseEvent *event) { QString text; text = QString("%1 X %2").arg(event->pos().x()).arg(event->pos().y()); // Global coordinate-system, but widget coord. position // QToolTip::showText(event->pos(), text); // this should fix it QToolTip::showText(this->mapToGlobal(event->pos()), text); }
Edit:
Played around a little with your example and draged an image in to test the actual annotation function... currently the annoations appear not on the image where you actually click in your scene...
This will fix it.void QEnhancedGraphicsView::slotPaintMarker(QPoint pos, int num) { QString stream; QTextStream(&stream) << "Paint marker: #" << num << " " << pos.x() << " " << pos.y() << "\n"; emit signalAddText(stream); qDebug() << "Paint Marker " << stream; QPixmap pix(50, 50); QPainter *painter = new QPainter(&pix); painter->setPen(QColor(0, 0, 0, 255)); painter->setBrush(QColor(255, 255, 255, 255)); painter->drawRect(0, 0, 49, 49); painter->setPen(Qt::black); painter->setFont(QFont("Verdana", 21, QFont::ExtraBold)); painter->drawText(QRect(0, 0, 50, 50), Qt::AlignCenter, QString::number(num)); delete painter; QGraphicsPixmapItem *anotation = new QGraphicsPixmapItem; anotation->setPixmap(pix); // #### FIX ############## QPointF pos_ = this->mapToScene(pos); anotation->setPos(pos_.x(), pos_.y()); // ######################### anotation->acceptDrops(); anotation->setFlag(QGraphicsItem::ItemIsMovable); anotation->setData(100, true); anotation->setData(101, num); this->scene()->addItem(anotation); }
Then it just depends on what your coordinates really need to show... currently they are showing the scene coords. So the first pixel of the image will not have (0,0), therefore the annotation also wont, but they depend on your scroll factor of your scene... Maybe you need/want to fix it later.
@Pl45m4 Thank you for your valuable and helpful advices.
I will try all this - and more important I need to study the documentation again.Because now I am confused when to use mapToScene, mapFromGlobal, maptoGlobal, widgetCoordinates and so on ...
What I want to do is:
- save marker coordinates that way, that I can simply reload those back to the scene, at same position as I have set them before
- all this regardless of monitor sizes, screen resolutions or image resolutions, scaling factors ...
-
@Pl45m4 Thank you for your valuable and helpful advices.
I will try all this - and more important I need to study the documentation again.Because now I am confused when to use mapToScene, mapFromGlobal, maptoGlobal, widgetCoordinates and so on ...
What I want to do is:
- save marker coordinates that way, that I can simply reload those back to the scene, at same position as I have set them before
- all this regardless of monitor sizes, screen resolutions or image resolutions, scaling factors ...
@ademmler said in Confusion with mouse coordinates:
Because now I am confused when to use mapToScene, mapFromGlobal, maptoGlobal, widgetCoordinates and so on ...
When? This is easy.. Every time you have different coordinate systems and you want to "sync" them (talking about the same point in both systems). Otherwise something happens like in your initial version.
You click(10, 10)
in scene- or in some widget's coords, but global(10, 10)
is somewhere else.
If you show something on screen (esp. when using static stuff likeQToolTip::show(...)
you can be sure, that it will most likely use the global/screen coordinate system. Therefore you need to map it to the coord. system of the widget where this point actually is.
"Map from" does the opposite thing. You have a point on your screen and want to know what this point might be inWidget X's
coordinates. So you translate it into the coords of the widget from where you call this mapping function.
For examplemyPushButton->mapFromGlobal(QPoint(100, 100));
This maps(100,100)
on your screen tomyPushButton
's coordinate system. If the button is located at(200, 200)
on your screen, it will output(-100, -100)
.What I want to do is:
save marker coordinates that way, that I can simply reload those back to the scene, at same position as I have set them before
Saving the annotation is simple, but I'm sure you want to save them, so that you can load the same image and they still point to the same location of the image where they got set initally, right?!
You have to save the zoom factor as well to ensure that they are still valid. Otherwise they could point somewhere else, when your scene does not have the same size and the image item does not have the same position in your scene.
Or you save your annotations relative to the coordinate system of your image (=QGraphicsPixmapItem
), assuming your annotation will always be on the image.
You will have to re-organize your annotations and how you map their positions anyway. So just try what fits best to your use case. -
@ademmler said in Confusion with mouse coordinates:
Because now I am confused when to use mapToScene, mapFromGlobal, maptoGlobal, widgetCoordinates and so on ...
When? This is easy.. Every time you have different coordinate systems and you want to "sync" them (talking about the same point in both systems). Otherwise something happens like in your initial version.
You click(10, 10)
in scene- or in some widget's coords, but global(10, 10)
is somewhere else.
If you show something on screen (esp. when using static stuff likeQToolTip::show(...)
you can be sure, that it will most likely use the global/screen coordinate system. Therefore you need to map it to the coord. system of the widget where this point actually is.
"Map from" does the opposite thing. You have a point on your screen and want to know what this point might be inWidget X's
coordinates. So you translate it into the coords of the widget from where you call this mapping function.
For examplemyPushButton->mapFromGlobal(QPoint(100, 100));
This maps(100,100)
on your screen tomyPushButton
's coordinate system. If the button is located at(200, 200)
on your screen, it will output(-100, -100)
.What I want to do is:
save marker coordinates that way, that I can simply reload those back to the scene, at same position as I have set them before
Saving the annotation is simple, but I'm sure you want to save them, so that you can load the same image and they still point to the same location of the image where they got set initally, right?!
You have to save the zoom factor as well to ensure that they are still valid. Otherwise they could point somewhere else, when your scene does not have the same size and the image item does not have the same position in your scene.
Or you save your annotations relative to the coordinate system of your image (=QGraphicsPixmapItem
), assuming your annotation will always be on the image.
You will have to re-organize your annotations and how you map their positions anyway. So just try what fits best to your use case.