PDA

View Full Version : Artificial mouse events



redbaron
10th August 2010, 17:20
Small toy app can be found here: http://gist.github.com/517445

I am trying to send artificial mouse event to widget and I use QApplication::sendEvent for that, next I check ev.isAccepted() and it returns False, even worse! Widget I've sent event to doesnt handle it (it is calendar widged and no date is picked) and I am in doubt that it even receives it, because I can see how mouseEventPressed is fired up on parent widget.



#include "calendar.h"

Calendar::Calendar(QWidget *parent) :
QWidget(parent)
{
qCal = new QCalendarWidget;
qBtn = new QPushButton(tr("Press me"));

connect(qBtn, SIGNAL(clicked()), this, SLOT(testCustomClick()));

QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(qCal);
layout->addWidget(qBtn);

setLayout(layout);
qDebug() << "Date:" << QDate::currentDate();
}

Calendar::~Calendar()
{
}

void Calendar::testCustomClick()
{
QMouseEvent qm2(QEvent::MouseButtonPress, QPoint(qCal->width()/2,qCal->height()/2), Qt::LeftButton , Qt::LeftButton, Qt::NoModifier);
QApplication::sendEvent(qCal, &qm2);

//this one is always False
qDebug() << "isAccepted: " << qm2.isAccepted();
}


void Calendar::mousePressEvent(QMouseEvent* ev)
{
//this is executed even for QMouseEvent which sended to qCal =((
//if we click on qCal with real mouse it is not executed
qDebug() << "mouse event: " << ev << "x=" << ev->x() <<" y=" << ev->y();
QWidget::mousePressEvent(ev);
}



I've done some search over forum and stackoverflow and found similair questions all of them are without solution =(

tobi
10th August 2010, 21:26
The reason for this not working is simple: To simulate a mouse click you have to send both a MouseButtonPress-Event AND a MouseButtonRelease-Event.
So try this:

void Calendar::testCustomClick()
{
{
QMouseEvent qm2(QEvent::MouseButtonPress, QPoint(qCal->width()/2,qCal->height()/2), Qt::LeftButton , Qt::LeftButton, Qt::NoModifier);
QApplication::sendEvent(qCal, &qm2);
}
{
QMouseEvent qm2(QEvent::MouseButtonRelease, QPoint(qCal->width()/2,qCal->height()/2), Qt::LeftButton , Qt::LeftButton, Qt::NoModifier);
QApplication::sendEvent(qCal, &qm2);
}
}

Cheers,
Tobi

redbaron
11th August 2010, 11:31
I've tried it as well, it doesnt work. I've digged into Qt source code and found
that sendEvent calls notify function which itself calls widget->event, but QCalendarWidget::event doesn't handle mouse events instead it call QTableView::event which itself ends up in QAbstractScrollArea::event which returns false on every mouse event.

What to do in such situation? How does real hardware mouse sends events to QCalendarWidget? Maybe it sends it to exact widget under cursor (not QCalendarWidget itself but smaller one which QCalendarWidget consist of?)