summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qcoreevent.h1
-rw-r--r--src/gui/graphicsview/qgraphicswidget.cpp8
-rw-r--r--tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp85
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"