diff options
-rw-r--r-- | src/qml/types/qqmltimer.cpp | 8 | ||||
-rw-r--r-- | tests/auto/qml/qqmltimer/tst_qqmltimer.cpp | 64 |
2 files changed, 69 insertions, 3 deletions
diff --git a/src/qml/types/qqmltimer.cpp b/src/qml/types/qqmltimer.cpp index ddadd6cc91..8cbcf7a349 100644 --- a/src/qml/types/qqmltimer.cpp +++ b/src/qml/types/qqmltimer.cpp @@ -329,7 +329,11 @@ bool QQmlTimer::event(QEvent *e) ticked(); return true; } else if (e->type() == QEvent_Triggered) { - emit triggered(); + if (d->running && d->pause.isStopped()) { + d->running = false; + emit triggered(); + emit runningChanged(); + } return true; } return QObject::event(e); @@ -340,10 +344,8 @@ void QQmlTimerPrivate::animationFinished(QAbstractAnimationJob *) Q_Q(QQmlTimer); if (repeating || !running) return; - running = false; firstTick = false; QCoreApplication::postEvent(q, new QEvent(QEvent_Triggered)); - emit q->runningChanged(); } QT_END_NAMESPACE diff --git a/tests/auto/qml/qqmltimer/tst_qqmltimer.cpp b/tests/auto/qml/qqmltimer/tst_qqmltimer.cpp index 3d24bcb715..b1e4bcab72 100644 --- a/tests/auto/qml/qqmltimer/tst_qqmltimer.cpp +++ b/tests/auto/qml/qqmltimer/tst_qqmltimer.cpp @@ -50,6 +50,23 @@ void consistentWait(int ms) QTest::qWait(20); } +void eventLoopWait(int ms) +{ + // QTest::qWait() always calls sendPostedEvents before exiting, so we can't use it to stop + // between an event is posted and it is received; But we can use an event loop instead + + QPauseAnimation waitTimer(ms); + waitTimer.start(); + while (waitTimer.state() == QAbstractAnimation::Running) + { + QTimer timer; + QEventLoop eventLoop; + timer.start(0); + timer.connect(&timer, &QTimer::timeout, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + } +} + class tst_qqmltimer : public QObject { Q_OBJECT @@ -69,6 +86,8 @@ private slots: void restartFromTriggered(); void runningFromTriggered(); void parentProperty(); + void stopWhenEventPosted(); + void restartWhenEventPosted(); }; class TimerHelper : public QObject @@ -396,6 +415,51 @@ void tst_qqmltimer::parentProperty() delete timer; } +void tst_qqmltimer::stopWhenEventPosted() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData(QByteArray("import QtQml 2.0\nTimer { interval: 200; running: true }"), QUrl::fromLocalFile("")); + QQmlTimer *timer = qobject_cast<QQmlTimer*>(component.create()); + + TimerHelper helper; + connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); + QCOMPARE(helper.count, 0); + + eventLoopWait(200); + QCOMPARE(helper.count, 0); + QVERIFY(timer->isRunning()); + timer->stop(); + QVERIFY(!timer->isRunning()); + + consistentWait(300); + QCOMPARE(helper.count, 0); +} + + +void tst_qqmltimer::restartWhenEventPosted() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData(QByteArray("import QtQml 2.0\nTimer { interval: 200; running: true }"), QUrl::fromLocalFile("")); + QQmlTimer *timer = qobject_cast<QQmlTimer*>(component.create()); + + TimerHelper helper; + connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); + QCOMPARE(helper.count, 0); + + eventLoopWait(200); + QCOMPARE(helper.count, 0); + timer->restart(); + + consistentWait(100); + QCOMPARE(helper.count, 0); + QVERIFY(timer->isRunning()); + + consistentWait(200); + QCOMPARE(helper.count, 1); +} + QTEST_MAIN(tst_qqmltimer) #include "tst_qqmltimer.moc" |