PDA

View Full Version : mouseMoveEvent contains wrong position?



draftpunk
10th September 2008, 13:50
Hello,

I have a small app that uses QGraphicsScene. I have several objects that have their own "selection handles", (small rectangles) which are children of the main objects. I'm trapping the mouseMoveEvents for the selection handles, but it seems that for the very first event, the event->pos() function returns scene coordinates instead of item coordinates. This results in the selection handle jumping whenever the user tries to move it. Here is the code:



#include "StdAfx.h"
#include "SelectionHandle.h"
#include "DrawingObject.h"
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QApplication>


CSelectionHandle::CSelectionHandle(qreal x, qreal y, int handleId, CDrawingObject* pParent, QGraphicsItem* pGraphicsParent)
: m_pParent(pParent), m_pGraphicsParent(pGraphicsParent)
{
Q_ASSERT(pParent != NULL);
Q_ASSERT(pGraphicsParent != NULL);

m_Id = handleId;
m_bHandleMoving = false;

// Create the graphics object for the handle
setRect(x-2, y-2, 4, 4);
pParent->m_pScene->addItem(this);

setBrush(QBrush(QColor("black")));
setParentItem(pGraphicsParent);
}


CSelectionHandle::~CSelectionHandle(void)
{
}

void CSelectionHandle::mousePressEvent( QGraphicsSceneMouseEvent *event )
{
m_bHandleMoving = true;
}

void CSelectionHandle::mouseMoveEvent( QGraphicsSceneMouseEvent *event )
{
QGraphicsItem::mouseMoveEvent(event);

if (m_bHandleMoving)
{
QPointF itemPos = pos();
QPointF eventPos, eventParentPos, eventScenePos;

eventPos = event->pos();
eventParentPos = mapToParent(eventPos);
eventScenePos = mapToScene(eventPos);

prepareGeometryChange();
setPos(eventParentPos);

m_pParent->MoveHandle(m_Id, eventParentPos);
}
else
{
QApplication::beep();
}
}

void CSelectionHandle::mouseReleaseEvent( QGraphicsSceneMouseEvent *event )
{
m_bHandleMoving = false;
}


After that first mouse move message goes through, the mouse move messages that follow are in item coordinates, as expected. Can anyone tell me what I am doing wrong here?

Thanks
draftpunk

aamer4yu
10th September 2008, 14:26
I guess ur selection handle is a graphics item.
Why are you implementing the move functionality ?
You just need to set flags on the item, and Qt will take care to move it.
Refer QGraphicsItem::setFlags

draftpunk
10th September 2008, 15:56
Why are you implementing the move functionality ?
You just need to set flags on the item, and Qt will take care to move it.

If I allow Qt to handle moving the selection handles, then the handles and parent move as one object. What I'm trying to do is to have the selection handle move independently of the parent object, for the purposes of changing the parent object's dimensions. I don't see any way to do this other than handling mouse movement messages of the selection handles. If there is a better way, please enlighten me!

aamer4yu
10th September 2008, 19:12
If I allow Qt to handle moving the selection handles, then the handles and parent move as one object.
I dont think so ;) . You must be setting the movable flag on the parent.
I tried a simple example where I added child graphicsitem in a parent graphics item. I set the setFlags(QGraphicsItem::ItemIsMovable) on the child item, and it works fine for me. Only the child moves.

I also set movable flag on the parent, so when i click parent, all the child items move with it, but when i move the item whose flag was set to movable, it moves. I also had other items which were fixed in the parent item.

Please try a small example urself and u will understand :)

draftpunk
10th September 2008, 22:10
You must be setting the movable flag on the parent.

Yes, both parent and child must be movable in this case. The user can move the parent object by dragging it, but can also resize the object by clicking and dragging a selection handle. In this situation, the object must change its size interactively, while the user drags the selection handle. This is why I must trap the mouse movement messages for the selection handle, so that I can resize the parent object on each mouse movement message of the selection handle.

I hope this helps explain the situation a little better. So anyway, I'm back to my original problem. On that first mouse movement message, the position returned by event->pos() is in terms of scene coordinates, rather than item coordinates. I can always just ignore this first message, but I would like to understand why this is happening.

Thanks!

aamer4yu
11th September 2008, 06:57
I guess I now understand what you are trying to do.
You want to keep the handle FIXED relative to the parent, while u want to change the geometry of the parent item. Am I right ?
Dont you think on mousemove event, you need to send signal to the parent item ?

Another thing, instead of using three mouse related functions, you can have a look at QGraphicsItem::itemChange .

Have a look at this (http://www.qt-apps.org/content/show.php/FotoWall?content=71316). It has what you want :)

yxmaomao
11th September 2008, 07:31
I guess, first time message is from viewport, if you want to know how the event are post, you can installEventFilter() for your widget then you could know what happened. Hope it could help you.

Sandip
11th September 2008, 09:17
hi draftpunk,

I have one different solution for your problem if I have understood your problem properly.
Please read it carefully.
Instead of two graphics items ( one child and one parent), you can have only one graphics item. You can draw the selection handle part on parent itself. In mousePressEvent, first determine whether user has clicked on selection handle portion, if yes then set the flag and don't propagate the event to super class. If no then let graphics item process the event.

In similar way, in mouseMoveEvent check for flag and if flag is set perform your operation otherwise you can just call QGraphicsItem::mouseMoveEvent(event) and it will move the graphics item on itself. You doesn't have to bother about it.

It is simple and works fine. Please let me know if it will solve your problem.

Enjoy Qt.

draftpunk
11th September 2008, 18:38
Great suggestions! Thanks to you all! I've been able to make some progress, found some issues with my code :o, and now, with your suggestions, I have some ideas for how to proceed. Thanks again!

aamer4yu
11th September 2008, 19:05
Did you have a look at the example link (http://www.qt-apps.org/content/show.php/FotoWall?content=71316) I posted before ??

draftpunk
12th September 2008, 02:59
Did you have a look at the example link (http://www.qt-apps.org/content/show.php/FotoWall?content=71316) I posted before ??

Yes, thanks for the link. That is very close to what I'm trying to do. I'm looking at the code right now to see what's going on. Thanks again.