diff options
-rw-r--r-- | src/corelib/kernel/qcoreevent.h | 1 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicswidget.cpp | 8 | ||||
-rw-r--r-- | tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp | 85 |
3 files changed, 93 insertions, 1 deletions
diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h index babb89d..75af3e7 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -324,6 +324,7 @@ private: friend class QGraphicsView; friend class QGraphicsViewPrivate; friend class QGraphicsScenePrivate; + friend class QGraphicsWidget; }; class Q_CORE_EXPORT QTimerEvent : public QEvent diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 157fbe5..033723a 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -168,6 +168,8 @@ QT_BEGIN_NAMESPACE \sa QGraphicsProxyWidget, QGraphicsItem, {Widgets and Layouts} */ +bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); + /*! Constructs a QGraphicsWidget instance. The optional \a parent argument is passed to QGraphicsItem's constructor. The optional \a wFlags argument @@ -1097,7 +1099,11 @@ QVariant QGraphicsWidget::propertyChange(const QString &propertyName, const QVar */ bool QGraphicsWidget::sceneEvent(QEvent *event) { - return QCoreApplication::sendEvent(this, event) || QGraphicsItem::sceneEvent(event); + bool spont = event->spontaneous(); + if (spont ? qt_sendSpontaneousEvent(this, event) : QApplication::sendEvent(this, event)) + return true; + event->spont = spont; + return QGraphicsItem::sceneEvent(event); } /*! diff --git a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp index 7536855..462dbfa 100644 --- a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp +++ b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp @@ -180,6 +180,7 @@ private slots: void comboboxWindowFlags(); void updateAndDelete(); void inputMethod(); + void clickFocus(); }; // Subclass that exposes the protected functions. @@ -3299,6 +3300,90 @@ void tst_QGraphicsProxyWidget::inputMethod() } } +void tst_QGraphicsProxyWidget::clickFocus() +{ + QGraphicsScene scene; + scene.setItemIndexMethod(QGraphicsScene::NoIndex); + QGraphicsProxyWidget *proxy = scene.addWidget(new QLineEdit); + + EventSpy proxySpy(proxy); + EventSpy widgetSpy(proxy->widget()); + + QGraphicsView view(&scene); + view.setFrameStyle(0); + view.resize(300, 300); + view.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&view); +#endif + QTest::qWait(250); + + QVERIFY(!proxy->hasFocus()); + QVERIFY(!proxy->widget()->hasFocus()); + + QCOMPARE(proxySpy.counts[QEvent::FocusIn], 0); + QCOMPARE(proxySpy.counts[QEvent::FocusOut], 0); + QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 0); + QCOMPARE(widgetSpy.counts[QEvent::FocusOut], 0); + + // Spontaneous mouse click sets focus on a clickable widget. + QPointF lineEditCenter = proxy->mapToScene(proxy->boundingRect().center()); + QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(lineEditCenter)); + QVERIFY(proxy->hasFocus()); + QVERIFY(proxy->widget()->hasFocus()); + QCOMPARE(proxySpy.counts[QEvent::FocusIn], 1); + QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 1); + + scene.setFocusItem(0); + QVERIFY(!proxy->hasFocus()); + QVERIFY(!proxy->widget()->hasFocus()); + QCOMPARE(proxySpy.counts[QEvent::FocusOut], 1); + QCOMPARE(widgetSpy.counts[QEvent::FocusOut], 1); + + // Non-spontaneous mouse click sets focus if the widget has been clicked before + { + QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress); + event.setScenePos(lineEditCenter); + event.setButton(Qt::LeftButton); + qApp->sendEvent(&scene, &event); + QVERIFY(proxy->hasFocus()); + QVERIFY(proxy->widget()->hasFocus()); + QCOMPARE(proxySpy.counts[QEvent::FocusIn], 2); + QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 2); + } + + scene.setFocusItem(0); + proxy->setWidget(new QLineEdit); // resets focusWidget + QVERIFY(!proxy->hasFocus()); + QVERIFY(!proxy->widget()->hasFocus()); + QCOMPARE(proxySpy.counts[QEvent::FocusOut], 2); + QCOMPARE(widgetSpy.counts[QEvent::FocusOut], 2); + + // Non-spontaneous mouse click does not set focus on the embedded widget. + { + QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress); + event.setScenePos(lineEditCenter); + event.setButton(Qt::LeftButton); + qApp->sendEvent(&scene, &event); + QVERIFY(!proxy->hasFocus()); + QVERIFY(!proxy->widget()->hasFocus()); + QCOMPARE(proxySpy.counts[QEvent::FocusIn], 2); + QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 2); + } + + scene.setFocusItem(0); + QVERIFY(!proxy->hasFocus()); + QVERIFY(!proxy->widget()->hasFocus()); + QCOMPARE(proxySpy.counts[QEvent::FocusOut], 2); + QCOMPARE(widgetSpy.counts[QEvent::FocusOut], 2); + + // Spontaneous click on non-clickable widget does not give focus. + proxy->widget()->setFocusPolicy(Qt::NoFocus); + QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(lineEditCenter)); + QVERIFY(!proxy->hasFocus()); + QVERIFY(!proxy->widget()->hasFocus()); +} + QTEST_MAIN(tst_QGraphicsProxyWidget) #include "tst_qgraphicsproxywidget.moc" |