diff options
author | Mitch Curtis <mitch.curtis@qt.io> | 2023-03-29 14:53:28 +0800 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2023-08-30 17:54:00 +0200 |
commit | bc6abc010ad5483240ac2e4ae6761864d37a7315 (patch) | |
tree | ac17e4e92e93d8f371c47bbe64b7b8a9fc43aaf0 | |
parent | 2a24f5fa1205cd3c39e01287929a27c73e69b16c (diff) |
Doc: add how-to for using C++ enums in JavaScript
The best search result for "qt how do i expose a C++ enum to
javascript" is currently a Qt Forum post, and the relevant information
in our docs is hard to find within QJSEngine's page.
Add a how-to to make it easier to find the answer.
Task-number: QTBUG-109634
Change-Id: Ia9c53c5d3826459655aa5b094c4d601b938ef3a3
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit c504227e235885199717129e7c05addd728361fa)
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
7 files changed, 178 insertions, 0 deletions
diff --git a/src/quick/doc/src/qtquick-how-tos.qdoc b/src/quick/doc/src/qtquick-how-tos.qdoc index ced360de6a..c030b071e2 100644 --- a/src/quick/doc/src/qtquick-how-tos.qdoc +++ b/src/quick/doc/src/qtquick-how-tos.qdoc @@ -17,6 +17,7 @@ \li \l {Call a C++ function from QML when a Button is clicked} \li \l {See which item has active focus} \li \l {Create a time picker like Android's TimePickerDialog} + \li \l {Use a C++ enum in JavaScript} \endlist @@ -73,4 +74,36 @@ \li \image how-to-time-picker-dark.png \caption TimePickerDialog in its dark theme. \endtable + + + \section1 Use a C++ enum in JavaScript + + To expose a C++ enum to JavaScript (that is, \l QJSEngine, not + \l QQmlEngine or \l QQmlApplicationEngine), use + \l QJSEngine::newQMetaObject(): + + \quotefromfile how-tos/how-to-cpp-enum-js/tst_how-to-cpp-enum-js.cpp + \skipto QJSEngine engine + \printuntil setProperty + \skipto Backend backend + \printuntil backend.load() + + The enum can then be used from JavaScript: + + \snippet how-tos/how-to-cpp-enum-js/script.mjs file + + When using \l QQmlEngine or \l QQmlApplicationEngine, there are easier + options; see + \l {Choosing the Correct Integration Method Between C++ and QML} + for more information. + + \c backend.h: + + \snippet how-tos/how-to-cpp-enum-js/backend.h file + + \c backend.cpp: + + \snippet how-tos/how-to-cpp-enum-js/backend.cpp file + + For more information, see \l {QObject Integration}. */ diff --git a/tests/auto/quick/doc/how-tos/CMakeLists.txt b/tests/auto/quick/doc/how-tos/CMakeLists.txt index 0e149c9e13..202ff38bb5 100644 --- a/tests/auto/quick/doc/how-tos/CMakeLists.txt +++ b/tests/auto/quick/doc/how-tos/CMakeLists.txt @@ -2,4 +2,5 @@ # SPDX-License-Identifier: BSD-3-Clause add_subdirectory(how-to-cpp-button) +add_subdirectory(how-to-cpp-enum-js) add_subdirectory(how-to-qml) diff --git a/tests/auto/quick/doc/how-tos/how-to-cpp-enum-js/CMakeLists.txt b/tests/auto/quick/doc/how-tos/how-to-cpp-enum-js/CMakeLists.txt new file mode 100644 index 0000000000..9030a81c93 --- /dev/null +++ b/tests/auto/quick/doc/how-tos/how-to-cpp-enum-js/CMakeLists.txt @@ -0,0 +1,19 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +qt_internal_add_test(tst_how-to-cpp-enum-js + SOURCES + backend.cpp + backend.h + tst_how-to-cpp-enum-js.cpp + LIBRARIES + Qt::Core + Qt::Qml +) + +qt_add_resources(tst_how-to-cpp-enum-js "js" + PREFIX + / + FILES + script.mjs +) diff --git a/tests/auto/quick/doc/how-tos/how-to-cpp-enum-js/backend.cpp b/tests/auto/quick/doc/how-tos/how-to-cpp-enum-js/backend.cpp new file mode 100644 index 0000000000..9062dbad3f --- /dev/null +++ b/tests/auto/quick/doc/how-tos/how-to-cpp-enum-js/backend.cpp @@ -0,0 +1,36 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +//! [file] +#include "backend.h" + +Backend::Backend(QJSEngine *engine) : + mEngine(engine) +{ +} + +bool Backend::load() +{ + // Do some loading here... + + const QJSValue module = mEngine->importModule(":/script.mjs"); + if (module.isError()) { + qWarning() << "Error loading script.mjs:" << module.toString(); + return false; + } + + const QJSValue function = module.property("backendStatusUpdate"); + if (!function.isCallable()) { + qWarning() << "backendStatusUpdate script function is not callable!"; + return false; + } + + const QJSValue functionResult = function.call(QJSValueList() << Loaded); + if (functionResult.isError()) { + qWarning() << "backendStatusUpdate script function had errors:" << functionResult.toString(); + return false; + } + + return true; +} +//! [file] diff --git a/tests/auto/quick/doc/how-tos/how-to-cpp-enum-js/backend.h b/tests/auto/quick/doc/how-tos/how-to-cpp-enum-js/backend.h new file mode 100644 index 0000000000..7dbc7149e1 --- /dev/null +++ b/tests/auto/quick/doc/how-tos/how-to-cpp-enum-js/backend.h @@ -0,0 +1,29 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +//! [file] +#include <QObject> +#include <QJSEngine> + +class Backend : public QObject +{ + Q_OBJECT + +public: + Backend(QJSEngine *engine); + + enum Status { + Unknown, + Error, + Loading, + Loaded + }; + + Q_ENUM(Status) + + bool load(); + +private: + QJSEngine *mEngine = nullptr; +}; +//! [file] diff --git a/tests/auto/quick/doc/how-tos/how-to-cpp-enum-js/script.mjs b/tests/auto/quick/doc/how-tos/how-to-cpp-enum-js/script.mjs new file mode 100644 index 0000000000..de1e49a168 --- /dev/null +++ b/tests/auto/quick/doc/how-tos/how-to-cpp-enum-js/script.mjs @@ -0,0 +1,13 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +//! [file] +export function backendStatusUpdate(backendStatus) { + if (backendStatus === Backend.Error) { + console.warn("Error!") + return + } + + console.log("Backend loaded successfully") +} +//! [file] diff --git a/tests/auto/quick/doc/how-tos/how-to-cpp-enum-js/tst_how-to-cpp-enum-js.cpp b/tests/auto/quick/doc/how-tos/how-to-cpp-enum-js/tst_how-to-cpp-enum-js.cpp new file mode 100644 index 0000000000..ab78784675 --- /dev/null +++ b/tests/auto/quick/doc/how-tos/how-to-cpp-enum-js/tst_how-to-cpp-enum-js.cpp @@ -0,0 +1,47 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include <QtCore/qregularexpression.h> +#include <QtTest/QtTest> +#include <QtQml/qjsengine.h> + +#include "backend.h" + +QT_BEGIN_NAMESPACE + +class tst_HowToCppEnumJs : public QObject +{ + Q_OBJECT + +public: + tst_HowToCppEnumJs(); + +private slots: + void example(); +}; + +tst_HowToCppEnumJs::tst_HowToCppEnumJs() +{ +} + +void tst_HowToCppEnumJs::example() +{ + QTest::failOnWarning(QRegularExpression(QStringLiteral(".?"))); + + QJSEngine engine; + engine.installExtensions(QJSEngine::AllExtensions); + + QJSValue backendJsMetaObject = engine.newQMetaObject(&Backend::staticMetaObject); + engine.globalObject().setProperty("Backend", backendJsMetaObject); + + QTest::ignoreMessage(QtDebugMsg, "Backend loaded successfully"); + Backend backend(&engine); + const bool loaded = backend.load(); + QVERIFY(loaded); +} + +QT_END_NAMESPACE + +QTEST_MAIN(tst_HowToCppEnumJs) + +#include "tst_how-to-cpp-enum-js.moc" |