QGraphicsProxyWidget: forward touch events to QWidget

When working with QGraphicsView/QGraphicsScene, touch events are sent to
QGraphicsView's viewport() event handler, which then dispatches it to the
corresponding QGraphicsItem, if any. In the case of QGraphicsProxyWidget, we
need to forward these touch events to the encapsulated QWidget, otherwise it
will never receive them (i.e. the event chain for touch events terminates at
QGraphicsProxyWidget).

This also enables QWidgets associated with QGraphicsProxyWidget to grab
gestures.

Task-id: QTBUG-45737
Change-Id: Ia441d3576afb6c97376be6f2ff073901e6e928a5
Reviewed-by: Andreas Aardal Hanssen <andreas@hanssen.name>
This commit is contained in:
Rafael Roquetto 2015-09-03 16:53:53 +00:00
parent 24d0f9ef5a
commit f5b682d320
2 changed files with 82 additions and 0 deletions

View File

@ -879,6 +879,19 @@ bool QGraphicsProxyWidget::event(QEvent *event)
break;
}
#endif
case QEvent::TouchBegin:
case QEvent::TouchUpdate:
case QEvent::TouchEnd: {
if (event->spontaneous())
qt_sendSpontaneousEvent(d->widget, event);
else
QApplication::sendEvent(d->widget, event);
if (event->isAccepted())
return true;
break;
}
default:
break;
}

View File

@ -179,6 +179,7 @@ private slots:
void mapToGlobal();
void mapToGlobalWithoutScene();
void QTBUG_43780_visibility();
void forwardTouchEvent();
};
// Subclass that exposes the protected functions.
@ -3760,5 +3761,73 @@ void tst_QGraphicsProxyWidget::QTBUG_43780_visibility()
QVERIFY(comboPopup->isVisible());
}
class TouchWidget : public QWidget
{
public:
TouchWidget(QWidget *parent = 0) : QWidget(parent) {}
bool event(QEvent *event)
{
switch (event->type()) {
case QEvent::TouchBegin:
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
event->accept();
return true;
break;
default:
break;
}
return QWidget::event(event);
}
};
// QTBUG_45737
void tst_QGraphicsProxyWidget::forwardTouchEvent()
{
QGraphicsScene *scene = new QGraphicsScene;
TouchWidget *widget = new TouchWidget;
widget->setAttribute(Qt::WA_AcceptTouchEvents);
QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget;
proxy->setAcceptTouchEvents(true);
proxy->setWidget(widget);
scene->addItem(proxy);
QGraphicsView *view = new QGraphicsView(scene);
view->show();
EventSpy eventSpy(widget);
QTouchDevice *device = new QTouchDevice;
device->setType(QTouchDevice::TouchScreen);
QWindowSystemInterface::registerTouchDevice(device);
QCOMPARE(eventSpy.counts[QEvent::TouchBegin], 0);
QCOMPARE(eventSpy.counts[QEvent::TouchUpdate], 0);
QCOMPARE(eventSpy.counts[QEvent::TouchEnd], 0);
QTest::touchEvent(view, device).press(0, QPoint(10, 10), view);
QTest::touchEvent(view, device).move(0, QPoint(15, 15), view);
QTest::touchEvent(view, device).move(0, QPoint(16, 16), view);
QTest::touchEvent(view, device).release(0, QPoint(15, 15), view);
QApplication::processEvents();
QCOMPARE(eventSpy.counts[QEvent::TouchBegin], 1);
QCOMPARE(eventSpy.counts[QEvent::TouchUpdate], 2);
QCOMPARE(eventSpy.counts[QEvent::TouchEnd], 1);
delete view;
delete proxy;
delete scene;
}
QTEST_MAIN(tst_QGraphicsProxyWidget)
#include "tst_qgraphicsproxywidget.moc"