PDA

View Full Version : Comparing QCursor::pos() to QGraphicsItem::pos()



mongooseblarg
6th March 2012, 20:39
I have a series of tiles (QGraphicsItems), let's say 100x100 of them.
Each are positioned 10 pixels apart using setPos().
They all show up correctly in a QGraphicsScene.

I'm trying to capture a QCursor position when QGraphicsView catches a mouseReleaseEvent().
However, the pos() for the QMouseEvent and QCursor:: pos() both give me weird coordinates.
I believe it has something to do with the level of zoom at the time of the mouse click, but I'm not sure.

So here's some code. The tiles' positions are started at (0,0) and are 10x10 pixels. So, if a mouse clicks the top-left-most tile at (5,5), tileAt() should return that first tile in the top left corner. However, the coordinates I'm getting for the QCursor(and QMouseEvent) are usually quite a bit higher than the tiles they're clicking on.

Here's the two relevant functions:


void GraphicsView::mouseReleaseEvent(QMouseEvent *e)
{
Tile* tile = tileAt(mapToGlobal(QCursor:: pos())); //or tileAt(mapToGlobal(e->pos()));
}

Tile* GraphicsView::tileAt(QPoint position)
{
for(int row=0; row<tiles.size(); row++)

if((mapToGlobal(tiles[row][0]->pos().toPoint()).y() + tiles[row][0]->height) < position.y())

for(int col=0; col<tiles[row].size(); col++)

if((mapToGlobal(tiles[row][col]->pos().toPoint()).x()+tiles[row][col]->width) < position.x())
return tiles[row][col];

return new Tile(-1,-1,this);
}


In this example, I was trying to use mapToGlobal on both the tiles' positions and the cursor position, but I still got weird numbers for the cursor. I've also tried using mapToScene on them.

Any idea how I can compare the positions of the tiles to the position of the cursor?

Thanks!

Spitfire
8th March 2012, 14:30
You've overdone it.



void GraphicsView::mouseReleaseEvent(QMouseEvent *e)
{
Tile* tile = tileAt( view->mapToScene( e->pos()) );
}

Tile* GraphicsView::tileAt( const QPointF& position) // QPointF not QPoint here
{
Tile* tile = NULL;
QGraphicsItem* item = scene->itemAt( position );
if( item && item->type() == YourDefinedTypeForThatItem ) // YourDefinedTypeForThatItem is a number returned from int type( void ) const which you have to implement in your Tile class;
{
tile = (Tile*)item;
}
return tile;
}


Basically - you use mapToScene() once, you get QPointF ( not QPoint! ) and then you can compare that position with position of your items.
Anyway, IMHO scene->itemAt() is the way to go for you.