diff options
author | Cavit Sina Dogru <sinadooru@gmail.com> | 2016-08-03 17:54:26 +0300 |
---|---|---|
committer | Cavit Sina Dogru <sinadooru@gmail.com> | 2016-08-09 17:16:44 +0000 |
commit | 4fbfbf7fe8e6f8f31b5704a0f8f55415a7284523 (patch) | |
tree | 71a71026465ea74e0e340d56e1121f0b2e99fad1 | |
parent | 9e9bf93deaec24d69fa76d0218e0235fc404c6b2 (diff) |
Qt object: Add exit(int)
This is similar to the Qt.quit() function but also specifies the return
code that the event loop will return.
[ChangeLog][QtQml] Added exit(int retCode) method to the Qt global object.
An application can call Qt.exit to specify a return code of the engine.
Task-number: QTBUG-54360
Change-Id: Iaa319e6dc4d6b99dc3a5c01845e87b936fd2cab0
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
-rw-r--r-- | src/qml/qml/qqmlapplicationengine.cpp | 1 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine.cpp | 19 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine.h | 1 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine_p.h | 1 | ||||
-rw-r--r-- | src/qml/qml/v8/qqmlbuiltinfunctions.cpp | 25 | ||||
-rw-r--r-- | src/qml/qml/v8/qqmlbuiltinfunctions_p.h | 1 | ||||
-rw-r--r-- | tests/auto/qml/qqmlqt/data/exit.qml | 7 | ||||
-rw-r--r-- | tests/auto/qml/qqmlqt/tst_qqmlqt.cpp | 15 | ||||
-rw-r--r-- | tools/qml/main.cpp | 17 | ||||
-rw-r--r-- | tools/qmlscene/main.cpp | 1 |
10 files changed, 85 insertions, 3 deletions
diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp index 30fc186391..fef2da753b 100644 --- a/src/qml/qml/qqmlapplicationengine.cpp +++ b/src/qml/qml/qqmlapplicationengine.cpp @@ -69,6 +69,7 @@ void QQmlApplicationEnginePrivate::init() q->connect(&statusMapper, SIGNAL(mapped(QObject*)), q, SLOT(_q_finishLoad(QObject*))); q->connect(q, SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit())); + q->connect(q, &QQmlApplicationEngine::exit, QCoreApplication::instance(), &QCoreApplication::exit); #ifndef QT_NO_TRANSLATION QTranslator* qtTranslator = new QTranslator; if (qtTranslator->load(QLatin1String("qt_") + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 2b49eae4de..cdaa9e83e9 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -982,8 +982,19 @@ QQmlEngine::~QQmlEngine() /*! \fn void QQmlEngine::quit() This signal is emitted when the QML loaded by the engine would like to quit. + + \sa exit() */ +/*! \fn void QQmlEngine::exit(int retCode) + This signal is emitted when the QML loaded by the engine would like to exit + from the event loop with the specified return code. + + \since 5.8 + \sa quit() + */ + + /*! \fn void QQmlEngine::warnings(const QList<QQmlError> &warnings) This signal is emitted when \a warnings messages are generated by QML. */ @@ -1837,6 +1848,14 @@ void QQmlEnginePrivate::sendQuit() } } +void QQmlEnginePrivate::sendExit(int retCode) +{ + Q_Q(QQmlEngine); + if (q->receivers(SIGNAL(exit(int))) == 0) + qWarning("Signal QQmlEngine::exit() emitted, but no receivers connected to handle it."); + emit q->exit(retCode); +} + static void dumpwarning(const QQmlError &error) { QMessageLogger(error.url().toString().toLatin1().constData(), diff --git a/src/qml/qml/qqmlengine.h b/src/qml/qml/qqmlengine.h index 132af78f80..bbb9c36ce9 100644 --- a/src/qml/qml/qqmlengine.h +++ b/src/qml/qml/qqmlengine.h @@ -155,6 +155,7 @@ protected: Q_SIGNALS: void quit(); + void exit(int retCode); void warnings(const QList<QQmlError> &warnings); private: diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index 949060f395..713b03dbf3 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -227,6 +227,7 @@ public: bool isScriptLoaded(const QUrl &url) const; void sendQuit(); + void sendExit(int retCode = 0); void warning(const QQmlError &); void warning(const QList<QQmlError> &); void warning(QQmlDelayedError *); diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 76a900c846..db0439ab9e 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -137,6 +137,7 @@ Heap::QtObject::QtObject(QQmlEngine *qmlEngine) o->defineDefaultProperty(QStringLiteral("darker"), QV4::QtObject::method_darker); o->defineDefaultProperty(QStringLiteral("tint"), QV4::QtObject::method_tint); o->defineDefaultProperty(QStringLiteral("quit"), QV4::QtObject::method_quit); + o->defineDefaultProperty(QStringLiteral("exit"), QV4::QtObject::method_exit); o->defineDefaultProperty(QStringLiteral("createQmlObject"), QV4::QtObject::method_createQmlObject); o->defineDefaultProperty(QStringLiteral("createComponent"), QV4::QtObject::method_createComponent); } @@ -992,6 +993,8 @@ This function causes the QQmlEngine::quit() signal to be emitted. Within the \l {Prototyping with qmlscene}, this causes the launcher application to exit; to quit a C++ application when this method is called, connect the QQmlEngine::quit() signal to the QCoreApplication::quit() slot. + +\sa exit() */ ReturnedValue QtObject::method_quit(CallContext *ctx) { @@ -1000,6 +1003,28 @@ ReturnedValue QtObject::method_quit(CallContext *ctx) } /*! + \qmlmethod Qt::exit(int retCode) + + This function causes the QQmlEngine::exit(int) signal to be emitted. + Within the \l {Prototyping with qmlscene}, this causes the launcher application to exit + the specified return code. To exit from the event loop with a specified return code when this + method is called, a C++ application can connect the QQmlEngine::exit(int) signal + to the QCoreApplication::exit(int) slot. + + \sa quit() +*/ +ReturnedValue QtObject::method_exit(CallContext *ctx) +{ + if (ctx->argc() != 1) + V4THROW_ERROR("Qt.exit(): Invalid arguments"); + + int retCode = ctx->args()[0].toNumber(); + + QQmlEnginePrivate::get(ctx->engine()->qmlEngine())->sendExit(retCode); + return QV4::Encode::undefined(); +} + +/*! \qmlmethod object Qt::createQmlObject(string qml, object parent, string filepath) Returns a new object created from the given \a string of QML which will have the specified \a parent, diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h index d29983c476..8c0759679a 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h +++ b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h @@ -122,6 +122,7 @@ struct QtObject : Object static ReturnedValue method_btoa(CallContext *ctx); static ReturnedValue method_atob(CallContext *ctx); static ReturnedValue method_quit(CallContext *ctx); + static ReturnedValue method_exit(CallContext *ctx); static ReturnedValue method_resolvedUrl(CallContext *ctx); static ReturnedValue method_createQmlObject(CallContext *ctx); static ReturnedValue method_createComponent(CallContext *ctx); diff --git a/tests/auto/qml/qqmlqt/data/exit.qml b/tests/auto/qml/qqmlqt/data/exit.qml new file mode 100644 index 0000000000..12727d9f04 --- /dev/null +++ b/tests/auto/qml/qqmlqt/data/exit.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +QtObject { + property int returnCode: -1 + Component.onCompleted: Qt.exit(returnCode) +} + diff --git a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp index 8150241e4a..69791085c5 100644 --- a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp +++ b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp @@ -87,6 +87,7 @@ private slots: void atob(); void fontFamilies(); void quit(); + void exit(); void resolvedUrl(); void later_data(); void later(); @@ -980,6 +981,20 @@ void tst_qqmlqt::quit() delete object; } +void tst_qqmlqt::exit() +{ + QQmlComponent component(&engine, testFileUrl("exit.qml")); + + QSignalSpy spy(&engine, &QQmlEngine::exit); + QObject *object = component.create(); + QVERIFY(object != Q_NULLPTR); + QCOMPARE(spy.count(), 1); + QList<QVariant> arguments = spy.takeFirst(); + QVERIFY(arguments.at(0).toInt() == object->property("returnCode").toInt()); + + delete object; +} + void tst_qqmlqt::resolvedUrl() { QQmlComponent component(&engine, testFileUrl("resolvedUrl.qml")); diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp index a795144984..d718067616 100644 --- a/tools/qml/main.cpp +++ b/tools/qml/main.cpp @@ -160,18 +160,23 @@ public: LoadWatcher(QQmlApplicationEngine *e, int expected) : QObject(e) , earlyExit(false) + , returnCode(0) , expect(expected) , haveOne(false) { connect(e, SIGNAL(objectCreated(QObject*,QUrl)), this, SLOT(checkFinished(QObject*))); // QQmlApplicationEngine also connects quit() to QCoreApplication::quit - // but if called before exec() then QCoreApplication::quit does nothing + // and exit() to QCoreApplication::exit but if called before exec() + // then QCoreApplication::quit or QCoreApplication::exit does nothing connect(e, SIGNAL(quit()), this, SLOT(quit())); + connect(e, &QQmlEngine::exit, + this, &LoadWatcher::exit); } bool earlyExit; + int returnCode; private: void contain(QObject *o, const QUrl &containPath); @@ -196,14 +201,20 @@ public Q_SLOTS: if (! --expect) { printf("qml: Did not load any objects, exiting.\n"); - exit(2);//Different return code from qFatal + std::exit(2);//Different return code from qFatal } } void quit() { //Will be checked before calling exec() earlyExit = true; + returnCode = 0; } + void exit(int retCode) { + earlyExit = true; + returnCode = retCode; + } + #if defined(QT_GUI_LIB) && !defined(QT_NO_OPENGL) void onOpenGlContextCreated(QOpenGLContext *context); #endif @@ -582,7 +593,7 @@ int main(int argc, char *argv[]) } if (lw->earlyExit) - return 0; + return lw->returnCode; return app->exec(); } diff --git a/tools/qmlscene/main.cpp b/tools/qmlscene/main.cpp index 1185a8e7ae..0e542ab0c8 100644 --- a/tools/qmlscene/main.cpp +++ b/tools/qmlscene/main.cpp @@ -564,6 +564,7 @@ int main(int argc, char ** argv) loadDummyDataFiles(engine, fi.path()); } QObject::connect(&engine, SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit())); + QObject::connect(&engine, &QQmlEngine::exit, QCoreApplication::instance(), &QCoreApplication::exit); component->loadUrl(options.url); while (component->isLoading()) QCoreApplication::processEvents(); |