Get mouse coordinates relative to Qt OpenGL widget - qt

I get my mouse coordinates like this:
winX = QCursor::pos().x();
These are coordinates for the whole screen. I need to get coordinates that are relative to my OpenGL widget window's viewport, so I can use the gluUnProject function.
How can I do that?

You might want to have a look at QWidget's mapFromGlobal(const QPoint & pos) method.
As per the documentation this:
translates the global screen coordinate pos to widget coordinates.

Related

QCursor::pos(); renders wrong coordinates

I have a floating widget which should follow mouse.
Now I have another widget, which sometimes changes its position.
Before any other widgets resize, everything's ok. After the change my coordinates always go astray and the floating widget is shifted, it floats at a distance from the mouse. I've noticed that the shift is somehow connected to window size, it grows when the size is bigger.
I pass to widget mouse coordinates with QCursor::pos();, and I also tried sending QPoint from other background widgets, over which it should float with mouseMoveEvent(QMouseEvent *event) and then QPoint{ mapToGlobal( { event->pos() } )};. These both render the same coordinates, and the same shift occurs.
E.g.
On a small window
Floater's coordinates QPoint(255,136)
Another widget's coordinates:
QPoint(0,0)
MapToGlobal from another widget: QPoint(255,136)
On a large window:
Floater's coordinates QPoint(205,86)
Another widget's coordinates: QPoint(0,0)
MapToGlobal from another widget: QPoint(205,86)
Can't grasp the problem, why it renders wrong coordinates.
The system is Qt 5.12.3. Any help will be appreciated.
UPD: The minimal reproducible example.
.h
class Area : public QWidget
{
Q_OBJECT
public:
void moveArea();
};
.cpp
void moveArea::Area()
{
move(QCursor::pos());
}
QCursor::pos() returns global (i.e. screen) coordinates but widget's position is measured in its parent's coordinate system if it has a parent. And is measured in global coordinates if and ONLY if the widget does not have any parent. So this code
void Area::moveArea()
{
move(QCursor::pos());
}
will move the upper left corner of Area object to the mouse cursor position ONLY if Area object is a top-level window, i.e. when it has no parent. If it has parent (which I believe is your case), you need to map global coordinates to parent's coordinates by changing your code to move(parentWidget()->mapFromGlobal(QCursor::pos()));.

How to get absolute coordinates with QGraphicsScene?

Let's say I have five objects, with the top-left red square and the larger black square both inserted into the scene at 0,0.
.
Later, let's say I want to move the bottom right corner of the black square to the bottom right corner of the bottom-right square. The most obvious thing to do would be:
bS.setRect( bS.rect().setBottomRight(redBR.rect().bottomRight) );
That's not exactly correct code, but the idea is simple. I would set the coordinate of the black square's bottom right corner to that of the red square's bottom right corner. Because that's where I want it to be. But in Qt, this seems to be impossible.
Because the call to redBR thinks it's at the origin. Every item thinks it's at the origin. Which means I can never know the coordinates of any item, anywhere, ever.
Is there a way to force QGraphicsScene to tell me the actual coordinates? Alternatively, is there some other graphics framework that uses real coordinates? I'm not going to insist on using Qt if there is no way to make it work.
Any help would be welcome. Please bear in mind my goal is not: "drag corner of box by manipulator". My goal is to be able to put items at coordinates whenever I want an item to be at a specific coordinate.
Edit:
Here's an example of what I mean. The big box hasn't been connected yet, so don't worry about it's coordinates. The problem is that if I don't remap the points coming out of the little box, every box believes it is at the origin. But if I do, then the y values vacillate between 0, 1, and -1.
The base class QGraphicsItem has quite some useful functionality for mapping between scene and item coordinates. One useful function is for mapping a point in item coordinates to scene coordinates:
QPointF QGraphicsItem::mapToScene(const QPointF &point)
There is however also a direct mapping available between points in different QGraphicsItems, which is probably the easiest to use here:
QPointF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPointF &point)
which can be used to map a point in redBR to a point in bS like:
bS.rect().setBottomRight(bS.mapFromItem( &redBR, redBR.rect().bottomRight() ) )

Getting the absolute location of a QT widget nested in multiple layouts

I'd like to get the absolute location of a QT widget that is a (horizontal) layout which is itself located in a central widget that has a layout.
I've tried the QWidget::mapToGlobal and QWidget::mapTo but I keep getting (0,0).
Edit
Here's my current implementation
QPoint p( 0 , 0 ); // Recall that widget 'lineEdit' is in a layout, which is itself in a layout
QPoint point = ui.lineEdit->mapToGlobal( p );
"Absolute location" is meaningless.
QWidget::mapToGlobal, as the docs state:-
"Translates the widget coordinate pos to global screen coordinates",
This is not want you want, as you mention in the comments that you're looking for "the position of the widget relative to the top left corner of the window"
You can use the function QWidget::mapTo, but note the following in the documentation:-
The parent must not be 0 and must be a parent of the calling widget.
From the code you've added to the example, it looks like you've used Qt Designer to create and setup the widgets. As you're calling mapToGlobal, there are only two reasons for the mapToGlobal to return (0, 0):-
1) The widget's top left corner is actually at the top left of the screen
2) I suspect you're calling the map functions before the window and its widgets have been displayed on the screen.
Without seeing all your code, I would say that no. 2 is the most likely issue here, so you're calling the mapping functions in something like the constructor of the MainWindow.

Draw 32x32 Tiled Images in QT

I'm curious to learn how to split an image into 32x32 (or really any size) selectable tiles and display them in Qt? An example is the Tiled Map Editor (the panel in the lower right corner of the screen). I'm thinking of trying to create a 2D level editor in Qt for fun but I'm fairly new to Qt and have yet to find the answer to this specific question. Or maybe I just don't know how to phrase the question.
Add your main image to a QPixmap, then for each tile that you want to create, call the QPixmap's copy function. This allows you to specify the area that you want to copy and returns you a new QPixmap with that area.
With each QPixmap tile you create using copy, use this to create a QGraphicsPixmapItem, which you then add to the QGraphicsScene.
So, you'd do something like this: -
// assuming your source image is in your resources qrc file
QPixmap srcImage(":/images/srcImage.png");
//in a loop for x and a 2nd loop for y
// copy a section of the source image
QPixmap tileImg = srcImage.copy(x, y, w, h);
// create the tile
QGraphicsPixmapItem* pTile = new QGraphicsPixmapItem(tileImg);
// add the pTile to the scene.
Using QGraphicsPixmapItem will provide you with a tiled object that can be positioned in the scene, selected and moved about.

QT pixel position from image when mouse click

I'm using QGraphicView and QGraphicScene to display and image. I would like to get image pixel coordinate when i mouse click on that pixel. For that i use mousePressEvent and implement function to isplay event position. But the problem is the image pixel position is wrong because i obtain the pixel coordinate corresponding to the GraphicView not the pixel coordinate in the image. I think it will gives me a right answer when the view have exactly the same size than the image (at least how to do that ?), but i preffer more sophisticated solution.
Please help
You override the mouse press event for QGraphicsPixmap item.

Resources