PDA

View Full Version : How to generate artifitial mouse events?



moridinbg
20th April 2009, 13:52
I would like to post artifitial mouse events in QGraphicsScene.
I have an application that parses some data and should be able to generate mouse clicks and moves based on it. Sometimes there may be several events at the same time.

I tried createing a new QGraphicsSceneMouseEvent and then set the data fields (setButton(), setPos(), setButtonDownPos(), etc) and then post the event to the Scene, but nothing happens.

Should I set absolutley everything (setPos, setScenePos, setLastPos, setLastScenePos) or setting just the scene positions is enaugh?

QbelcorT
20th April 2009, 14:34
Hi,
I did this for 'keypress' events using QCoreApplication::sendEvent, you can send any events with this function. There is even a mousepressevent example in the function code.


QMouseEvent event(QEvent::MouseButtonPress, pos, 0, 0, 0);
QApplication::sendEvent(mainWindow, &event);

moridinbg
20th April 2009, 14:47
Yes, I have read it, but it is not working for me with QGraphicsScene.
I have a graphics item with reimplemented mousePressEvent, and I am outputting the event coordinates on click, so I know that it works with just clicking with the mouse.
But posting a new QGraphicsSceneMouseEvent (or justQMouseEvent) with the correct buttonDown and position coordinates does nothing.

QGraphicsScene::event() returns false with my manually posted events.

QbelcorT
20th April 2009, 14:54
Are you posting the event to the correct object? Please provide an example of how you are posting the event using this method.

moridinbg
20th April 2009, 15:10
I am posting it to the right object for sure. I derived a class from QGraphicsScene and reimplemented QGraphicsScene::event().
I am posting a custom event to the scene with the coordinates of the desired mouse click and unique id (as I said there may be several clicks at the same time).
In the derived event() implementation I am successfully capturing the custom event and create a new QGraphicsSceneMouseEvent with the coordinates, which I am then passing to the base QGraphicsScene::event() function.
That's where nothing happens.


bool MyScene::event(QEvent *event)
{
if(event->type() == QEvent::User)
{
qDebug() << "Received!";
QGraphicsSceneMouseEvent *click = new QGraphicsSceneMouseEvent();
click->setButton(Qt::LeftButton);
click->setScenePos(QPointF(((MyEvent *)event)->getX(), ((MyEvent *)event)->getY()));
click->setButtonDownScenePos(Qt::LeftButton, QPointF(((MyEvent *)event)->getX(), ((MyEvent *)event)->getY()));
click->setLastScenePos(QPointF(((MyEvent *)event)->getX(), (((MyEvent *)event)->getY())));
return QGraphicsScene::event(click);
}
else
return QGraphicsScene::event(event);
}

QbelcorT
20th April 2009, 15:47
I assume you have a QGraphicsView in which the scene is using as a view?
I am looking at the QGraphicsSceneMouseEvent and it says.. "When a QGraphicsView receives a QMouseEvent, it translates it to a QGraphicsSceneMouseEvent. The event is then forwarded to the QGraphicsScene associated with the view"
Make sure you are posting the 'artificial' event to your view (QWidget/QGraphicsView), your 'view' will then forward that 'artificial' event to your scene.
see QMouseEvent. Where is this "event->type() == QEvent::User" this user event being posted from? FYI.. be careful of that 'new' operator in the event handler, make sure you are freeing your memory somewhere logical.

moridinbg
20th April 2009, 16:30
I am creating the events in the MainWindow.
I have already tried to send the event to the view, but nothing happens again?!
I even set it to setInteractive(true) although it should be enabled by default.
The code is:


void MainWindow::click()
{
QMouseEvent click(QEvent::MouseButtonPress, QPoint(126,575), Qt::LeftButton, 0, 0);
click.setAccepted(true);
QCoreApplication::sendEvent(m_view, &click);
}


I am checking incoming events in the scene derived class and there are no QGraphicsSceneMouseEvents, unless I click with the mouse.

These are the scene and view initializations:


m_scene = new MyScene();
m_scene->setSceneRect(0, 0, 600, 600);
m_scene->setItemIndexMethod(QGraphicsScene::NoIndex);
m_scene->setBackgroundBrush(Qt::red);

m_view = new QGraphicsView(m_scene);
m_view->setRenderHint(QPainter::Antialiasing);
m_view->setCacheMode(QGraphicsView::CacheBackground);
m_view->setViewportUpdateMode(QGraphicsView::BoundingRectV iewportUpdate);
m_view->setInteractive(true);
m_view->show();