diff options
author | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2009-07-14 11:03:10 (GMT) |
---|---|---|
committer | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2009-07-14 11:32:47 (GMT) |
commit | a2bad25383e565233a0c2527e04cef9f6b577f14 (patch) | |
tree | e62e3c89500eaccedb19b864b1351f0d19a8b910 | |
parent | 9210e8cdc83b6812d10f5f5847d05703ef2e5f7c (diff) | |
download | Qt-a2bad25383e565233a0c2527e04cef9f6b577f14.zip Qt-a2bad25383e565233a0c2527e04cef9f6b577f14.tar.gz Qt-a2bad25383e565233a0c2527e04cef9f6b577f14.tar.bz2 |
Make sure QGraphicsScene::update() only requires one event-loop
iteration before the views are updated.
A full scene update (scene.update()) already supported it because the
scene called update() on the views directly. However, partially scene
updates (scene.update(rect)) required two event-loop iterations
before the views were updated.
Auto-test included.
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene.cpp | 14 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsview.cpp | 10 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsview_p.h | 10 | ||||
-rw-r--r-- | tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp | 27 |
4 files changed, 46 insertions, 15 deletions
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index c8e178a..48d8788 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -357,6 +357,9 @@ void QGraphicsScenePrivate::_q_emitUpdated() updateAll = false; for (int i = 0; i < views.size(); ++i) views.at(i)->d_func()->processPendingUpdates(); + // It's important that we update all views before we dispatch, hence two for-loops. + for (int i = 0; i < views.size(); ++i) + views.at(i)->d_func()->dispatchPendingUpdateRequests(); return; } @@ -447,13 +450,8 @@ void QGraphicsScenePrivate::_q_processDirtyItems() } // Immediately dispatch all pending update requests on the views. - for (int i = 0; i < views.size(); ++i) { - QWidget *viewport = views.at(i)->d_func()->viewport; - if (qt_widget_private(viewport)->paintOnScreen()) - QCoreApplication::sendPostedEvents(viewport, QEvent::UpdateRequest); - else - QCoreApplication::sendPostedEvents(viewport->window(), QEvent::UpdateRequest); - } + for (int i = 0; i < views.size(); ++i) + views.at(i)->d_func()->dispatchPendingUpdateRequests(); } /*! @@ -2730,7 +2728,7 @@ void QGraphicsScene::update(const QRectF &rect) if (directUpdates) { // Update all views. for (int i = 0; i < d->views.size(); ++i) - d->views.at(i)->d_func()->updateAll(); + d->views.at(i)->d_func()->fullUpdatePending = true; } } else { if (directUpdates) { diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index bcfd68c..1cea8db 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -821,13 +821,9 @@ void QGraphicsViewPrivate::processPendingUpdates() if (!scene) return; - if (fullUpdatePending) { // We have already called viewport->update() - dirtyBoundingRect = QRect(); - dirtyRegion = QRegion(); - return; - } - - if (viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate) { + if (fullUpdatePending) { + viewport->update(); + } else if (viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate) { if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing) viewport->update(dirtyBoundingRect.adjusted(-1, -1, 1, 1)); else diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h index 0fa8b34..62a2b84 100644 --- a/src/gui/graphicsview/qgraphicsview_p.h +++ b/src/gui/graphicsview/qgraphicsview_p.h @@ -58,6 +58,7 @@ #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW #include <QtGui/qevent.h> +#include <QtCore/qcoreapplication.h> #include "qgraphicssceneevent.h" #include <QtGui/qstyleoption.h> #include <private/qabstractscrollarea_p.h> @@ -168,6 +169,15 @@ public: dirtyBoundingRect = QRect(); dirtyRegion = QRegion(); } + + inline void dispatchPendingUpdateRequests() + { + if (qt_widget_private(viewport)->paintOnScreen()) + QCoreApplication::sendPostedEvents(viewport, QEvent::UpdateRequest); + else + QCoreApplication::sendPostedEvents(viewport->window(), QEvent::UpdateRequest); + } + bool updateRect(const QRect &rect); bool updateRegion(const QRegion ®ion); bool updateSceneSlotReimplementedChecked; diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index e9d6f1d..f7ea4ce 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -236,6 +236,7 @@ private slots: void contextMenuEvent(); void contextMenuEvent_ItemIgnoresTransformations(); void update(); + void update2(); void views(); void event(); void eventsToDisabledItems(); @@ -2779,6 +2780,32 @@ void tst_QGraphicsScene::update() QCOMPARE(region, QRectF(-100, -100, 200, 200)); } +void tst_QGraphicsScene::update2() +{ + QGraphicsScene scene; + scene.setSceneRect(-200, -200, 200, 200); + CustomView view; + view.setScene(&scene); + view.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&view); +#endif + QTest::qWait(250); + view.repaints = 0; + + // Make sure QGraphicsScene::update only requires one event-loop iteration + // before the view is updated. + scene.update(); + qApp->processEvents(); + QCOMPARE(view.repaints, 1); + view.repaints = 0; + + // The same for partial scene updates. + scene.update(QRectF(-100, -100, 100, 100)); + qApp->processEvents(); + QCOMPARE(view.repaints, 1); +} + void tst_QGraphicsScene::views() { QGraphicsScene scene; |