Support QML type registration split: build system + tools integration
This change addresses the following issue: - Module A wants to have an optional QML API without depending on declarative (e.g., because it has a C++ only API usable for Widgets based applications that normally would not link against declarative). - Thus we add a module B with all the QML support (type registration, maybe additional types/functions/image providers). - Currently, this would require to wrap every type from module A into QML_FOREIGN manually, adding large amounts of boilerplate. To solve this, we extend qmltyperegistrar and the CMake API: - qmltyperegistrar gains a new --extract option to generate a file with all QML_FOREIGN declarations. More precisely, it generates a header and source file; the source file includes the header and the moc generated file. - We expose this in cmake via a new qt6_generate_foreign_qml_types function. That function takes two targets, the source library's target and the QML module's target. It then runs qmltyperegistrar on the source library, and adds the generated files to the QML module's target, and adds the proper dependencies between the targets. The remaining step to achieve the goal of split registration is to provide the QML registration macros in a separate header. Task-number: QTBUG-92258 Change-Id: I51c4ef660ca7476b556b1991a6c76bbcad2c69af Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
This commit is contained in:
parent
a3deb2ff59
commit
96c1337aef
|
@ -1881,6 +1881,48 @@ if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
|
|||
endfunction()
|
||||
endif()
|
||||
|
||||
function(qt6_generate_foreign_qml_types lib_target qml_target)
|
||||
|
||||
qt6_extract_metatypes(${lib_target})
|
||||
get_target_property(target_metatypes_json_file ${lib_target} INTERFACE_QT_META_TYPES_BUILD_FILE)
|
||||
if (NOT target_metatypes_json_file)
|
||||
message(FATAL_ERROR "Need target metatypes.json file")
|
||||
endif()
|
||||
|
||||
set(registration_files_base ${lib_target}_${qml_target})
|
||||
set(additional_sources ${registration_files_base}.cpp ${registration_files_base}.h)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${additional_sources}
|
||||
DEPENDS
|
||||
${target}
|
||||
${target_metatypes_json_file}
|
||||
${QT_CMAKE_EXPORT_NAMESPACE}::qmltyperegistrar
|
||||
COMMAND
|
||||
${QT_TOOL_COMMAND_WRAPPER_PATH}
|
||||
$<TARGET_FILE:${QT_CMAKE_EXPORT_NAMESPACE}::qmltyperegistrar>
|
||||
"--extract"
|
||||
-o ${registration_files_base}
|
||||
${target_metatypes_json_file}
|
||||
COMMENT "Generate QML registration code for target ${target}"
|
||||
)
|
||||
|
||||
target_sources(${qml_target} PRIVATE ${additional_sources})
|
||||
qt6_wrap_cpp(${additional_sources} TARGET ${qml_target})
|
||||
endfunction()
|
||||
|
||||
|
||||
if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
|
||||
if(QT_DEFAULT_MAJOR_VERSION EQUAL 6)
|
||||
function(qt_generate_foreign_qml_types)
|
||||
qt6_generate_foreign_qml_types(${ARGV})
|
||||
endfunction()
|
||||
else()
|
||||
message(FATAL_ERROR "qt_generate_foreign_qml_types() is only available in Qt 6.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# target: Expected to be the backing target for a qml module. Certain target
|
||||
# properties normally set by qt6_add_qml_module() will be retrieved from this
|
||||
# target. (REQUIRED)
|
||||
|
|
|
@ -133,6 +133,60 @@ void MetaTypesJsonProcessor::postProcessForeignTypes()
|
|||
sortTypes(m_types);
|
||||
}
|
||||
|
||||
QString MetaTypesJsonProcessor::extractRegisteredTypes() const
|
||||
{
|
||||
QString registrationHelper;
|
||||
for (const auto &obj: m_types) {
|
||||
const QString className = obj[u"className"].toString();
|
||||
const QString foreignClassName = className+ u"Foreign";
|
||||
const auto classInfos = obj[u"classInfos"].toArray();
|
||||
QString qmlElement;
|
||||
QString qmlUncreatable;
|
||||
QString qmlAttached;
|
||||
bool isSingleton = false;
|
||||
bool isExplicitlyUncreatable = false;
|
||||
for (QJsonValue entry: classInfos) {
|
||||
const auto name = entry[u"name"].toString();
|
||||
const auto value = entry[u"value"].toString();
|
||||
if (name == u"QML.Element") {
|
||||
if (value == u"auto") {
|
||||
qmlElement = u"QML_NAMED_ELEMENT("_qs + className + u")"_qs;
|
||||
} else if (value == u"anonymous") {
|
||||
qmlElement = u"QML_ANONYMOUS"_qs;
|
||||
} else {
|
||||
qmlElement = u"QML_NAMED_ELEMENT(" + value + u")";
|
||||
}
|
||||
} else if (name == u"QML.Creatable" && value == u"false") {
|
||||
isExplicitlyUncreatable = true;
|
||||
} else if (name == u"QML.UncreatableReason") {
|
||||
qmlUncreatable = u"QML_UNCREATABLE(\"" + value + u"\")";
|
||||
} else if (name == u"QML.Attached") {
|
||||
qmlAttached = u"QML_ATTACHED("_qs + value + u")";
|
||||
} else if (name == u"QML.Singleton") {
|
||||
isSingleton = true;
|
||||
}
|
||||
}
|
||||
if (qmlElement.isEmpty())
|
||||
continue; // no relevant entries found
|
||||
const QString spaces = u" "_qs;
|
||||
registrationHelper += u"\nstruct "_qs + foreignClassName + u"{\n Q_GADGET\n"_qs;
|
||||
registrationHelper += spaces + u"QML_FOREIGN(" + className + u")\n"_qs;
|
||||
registrationHelper += spaces + qmlElement + u"\n"_qs;
|
||||
if (isSingleton)
|
||||
registrationHelper += spaces + u"QML_SINGLETON\n"_qs;
|
||||
if (isExplicitlyUncreatable) {
|
||||
if (qmlUncreatable.isEmpty())
|
||||
registrationHelper += spaces + uR"(QML_UNCREATABLE(""))" + u"n";
|
||||
else
|
||||
registrationHelper += spaces + qmlUncreatable + u"\n";
|
||||
}
|
||||
if (!qmlAttached.isEmpty())
|
||||
registrationHelper += spaces + qmlAttached + u"\n";
|
||||
registrationHelper += u"};\n";
|
||||
}
|
||||
return registrationHelper;
|
||||
}
|
||||
|
||||
MetaTypesJsonProcessor::RegistrationMode MetaTypesJsonProcessor::qmlTypeRegistrationMode(
|
||||
const QJsonObject &classDef)
|
||||
{
|
||||
|
|
|
@ -51,6 +51,8 @@ public:
|
|||
QStringList referencedTypes() const { return m_referencedTypes; }
|
||||
QStringList includes() const { return m_includes; }
|
||||
|
||||
QString extractRegisteredTypes() const;
|
||||
|
||||
private:
|
||||
enum RegistrationMode {
|
||||
NoRegistration,
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <QFile>
|
||||
#include <QScopedPointer>
|
||||
#include <QSaveFile>
|
||||
#include <QFileInfo>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
|
@ -75,6 +76,40 @@ static bool argumentsFromCommandLineAndFile(QStringList &allArguments, const QSt
|
|||
return true;
|
||||
}
|
||||
|
||||
static int runExtract(const QString & baseName, const MetaTypesJsonProcessor &processor) {
|
||||
if (processor.types().isEmpty()) {
|
||||
fprintf(stderr, "Error: No types to register found in library\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
QFile headerFile(baseName + u".h");
|
||||
bool ok = headerFile.open(QFile::WriteOnly);
|
||||
if (!ok) {
|
||||
fprintf(stderr, "Error: Cannot open %s for writing\n", qPrintable(headerFile.fileName()));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
auto prefix = QString::fromLatin1(
|
||||
"#ifndef %1_H\n"
|
||||
"#define %1_H\n"
|
||||
"#include <QtQml/qqml.h>\n"
|
||||
"#include <QtQml/qqmlmoduleregistration.h>\n").arg(baseName.toUpper());
|
||||
const QStringList includes = processor.includes();
|
||||
for (const QString &include: includes)
|
||||
prefix += u"\n#include <%1>"_qs.arg(include);
|
||||
headerFile.write((prefix + processor.extractRegisteredTypes()).toUtf8() + "\n#endif");
|
||||
|
||||
QFile sourceFile(baseName + u".cpp");
|
||||
ok = sourceFile.open(QFile::WriteOnly);
|
||||
if (!ok) {
|
||||
fprintf(stderr, "Error: Cannot open %s for writing\n", qPrintable(sourceFile.fileName()));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
// the string split is necessaury because cmake's automoc scanner would otherwise pick up the include
|
||||
QString code = u"#include \"%1.h\"\n#include "_qs.arg(baseName);
|
||||
code += uR"("moc_%1.cpp")"_qs.arg(baseName);
|
||||
sourceFile.write(code.toUtf8());
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Produce reliably the same output for the same input by disabling QHash's random seeding.
|
||||
|
@ -144,6 +179,10 @@ int main(int argc, char **argv)
|
|||
"want to follow Qt's versioning scheme."));
|
||||
parser.addOption(followForeignVersioningOption);
|
||||
|
||||
QCommandLineOption extract(u"extract"_qs);
|
||||
extract.setDescription(u"Extract QML types from a module and use QML_FOREIGN to register them"_qs);
|
||||
parser.addOption(extract);
|
||||
|
||||
parser.addPositionalArgument(QStringLiteral("[MOC generated json file]"),
|
||||
QStringLiteral("MOC generated json output."));
|
||||
|
||||
|
@ -153,10 +192,35 @@ int main(int argc, char **argv)
|
|||
|
||||
parser.process(arguments);
|
||||
|
||||
const QString module = parser.value(importNameOption);
|
||||
|
||||
MetaTypesJsonProcessor processor(parser.isSet(privateIncludesOption));
|
||||
if (!processor.processTypes(parser.positionalArguments()))
|
||||
return EXIT_FAILURE;
|
||||
|
||||
processor.postProcessTypes();
|
||||
|
||||
if (parser.isSet(foreignTypesOption))
|
||||
processor.processForeignTypes(parser.value(foreignTypesOption).split(QLatin1Char(',')));
|
||||
|
||||
processor.postProcessForeignTypes();
|
||||
|
||||
|
||||
if (parser.isSet(extract)) {
|
||||
if (!parser.isSet(outputOption)) {
|
||||
fprintf(stderr, "Error: The output file name must be provided\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
QString baseName = parser.value(outputOption);
|
||||
return runExtract(baseName, processor);
|
||||
}
|
||||
|
||||
FILE *output = stdout;
|
||||
QScopedPointer<FILE, ScopedPointerFileCloser> outputFile;
|
||||
|
||||
|
||||
if (parser.isSet(outputOption)) {
|
||||
// extract does its own file handling
|
||||
QString outputName = parser.value(outputOption);
|
||||
#if defined(_MSC_VER)
|
||||
if (_wfopen_s(&output, reinterpret_cast<const wchar_t *>(outputName.utf16()), L"w") != 0) {
|
||||
|
@ -180,19 +244,6 @@ int main(int argc, char **argv)
|
|||
"#include <QtQml/qqml.h>\n"
|
||||
"#include <QtQml/qqmlmoduleregistration.h>\n");
|
||||
|
||||
const QString module = parser.value(importNameOption);
|
||||
|
||||
MetaTypesJsonProcessor processor(parser.isSet(privateIncludesOption));
|
||||
if (!processor.processTypes(parser.positionalArguments()))
|
||||
return EXIT_FAILURE;
|
||||
|
||||
processor.postProcessTypes();
|
||||
|
||||
if (parser.isSet(foreignTypesOption))
|
||||
processor.processForeignTypes(parser.value(foreignTypesOption).split(QLatin1Char(',')));
|
||||
|
||||
processor.postProcessForeignTypes();
|
||||
|
||||
const QStringList includes = processor.includes();
|
||||
for (const QString &include : includes)
|
||||
fprintf(output, "\n#include <%s>", qPrintable(include));
|
||||
|
|
|
@ -44,6 +44,7 @@ if(TARGET Qt::Quick)
|
|||
endif()
|
||||
add_subdirectory(qqmljsscope)
|
||||
endif()
|
||||
add_subdirectory(qmlsplitlib)
|
||||
if(TARGET Qt::Widgets)
|
||||
add_subdirectory(qjsengine)
|
||||
add_subdirectory(qjsvalue)
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
include(GenerateExportHeader)
|
||||
|
||||
qt_add_library(tst_qmlsplitlib_library
|
||||
lib.h
|
||||
lib.cpp
|
||||
)
|
||||
qt_autogen_tools_initial_setup(tst_qmlsplitlib_library)
|
||||
target_include_directories(tst_qmlsplitlib_library PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) # find autogenerated header
|
||||
generate_export_header(tst_qmlsplitlib_library)
|
||||
|
||||
target_link_libraries(tst_qmlsplitlib_library Qt::Core)
|
||||
|
||||
qt_internal_add_test(tst_qmlsplitlib
|
||||
SOURCES
|
||||
tst_qmlsplitlib.cpp
|
||||
LIBRARIES
|
||||
Qt::Core
|
||||
Qt::Qml
|
||||
)
|
||||
qt_autogen_tools_initial_setup(tst_qmlsplitlib)
|
||||
|
||||
qt6_generate_foreign_qml_types(tst_qmlsplitlib_library tst_qmlsplitlib)
|
||||
|
||||
qt6_add_qml_module(tst_qmlsplitlib
|
||||
VERSION 1.0
|
||||
URI "SplitLib"
|
||||
QML_FILES
|
||||
main.qml
|
||||
)
|
||||
|
||||
target_link_libraries(tst_qmlsplitlib PRIVATE tst_qmlsplitlib_library)
|
|
@ -0,0 +1,5 @@
|
|||
#include "lib.h"
|
||||
|
||||
bool SplitLib::transmogrify() { return true; }
|
||||
|
||||
#include "moc_lib.cpp"
|
|
@ -0,0 +1,84 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef SPLITLIB_LIB_H
|
||||
#define SPLITLIB_LIB_H
|
||||
#include "tst_qmlsplitlib_library_export.h"
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QObject>
|
||||
|
||||
// FIXME: should at some point be in qtbase or separate repo
|
||||
// taken from qqmlregistration.h
|
||||
#define QML_ELEMENT \
|
||||
Q_CLASSINFO("QML.Element", "auto")
|
||||
|
||||
#define QML_PRIVATE_NAMESPACE \
|
||||
QT_PREPEND_NAMESPACE(QQmlPrivate)
|
||||
|
||||
#define QML_REGISTER_TYPES_AND_REVISIONS \
|
||||
QT_PREPEND_NAMESPACE(qmlRegisterTypesAndRevisions)
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace QQmlPrivate {
|
||||
template<typename, typename> struct QmlSingleton;
|
||||
|
||||
}
|
||||
template<typename T, typename... Args>
|
||||
void qmlRegisterTypesAndRevisions(const char *uri, int versionMajor, QList<int> *);
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#define QML_SINGLETON \
|
||||
Q_CLASSINFO("QML.Singleton", "true") \
|
||||
enum class QmlIsSingleton {yes = true}; \
|
||||
template<typename, typename> friend struct QML_PRIVATE_NAMESPACE::QmlSingleton; \
|
||||
template<typename T, typename... Args> \
|
||||
friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor, QList<int> *);
|
||||
|
||||
#define QML_NAMED_ELEMENT(NAME) \
|
||||
Q_CLASSINFO("QML.Element", #NAME)
|
||||
|
||||
class TST_QMLSPLITLIB_LIBRARY_EXPORT SplitLib : public QObject
|
||||
{
|
||||
public:
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
|
||||
Q_INVOKABLE bool transmogrify();
|
||||
};
|
||||
|
||||
|
||||
class TST_QMLSPLITLIB_LIBRARY_EXPORT Foo : public QObject
|
||||
{
|
||||
public:
|
||||
Q_OBJECT
|
||||
QML_NAMED_ELEMENT(Bar)
|
||||
QML_SINGLETON
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,55 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import SplitLib
|
||||
|
||||
SplitLib {
|
||||
property string s: Bar.objectName
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtQml/qqmlextensionplugin.h>
|
||||
|
||||
Q_IMPORT_QML_PLUGIN(TimeExamplePlugin)
|
||||
Q_IMPORT_QML_PLUGIN(BasicExtension)
|
|
@ -0,0 +1,54 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QQmlEngine>
|
||||
#include <QQmlComponent>
|
||||
#include <QObject>
|
||||
#include <qtest.h>
|
||||
#include "lib.h"
|
||||
|
||||
class tst_splitlib : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void verifyComponent();
|
||||
};
|
||||
|
||||
void tst_splitlib::verifyComponent()
|
||||
{
|
||||
QQmlEngine engine;
|
||||
QQmlComponent c(&engine, QStringLiteral("qrc:/SplitLib/main.qml"));
|
||||
QVERIFY2(c.isReady(), qPrintable(c.errorString()));
|
||||
QScopedPointer o(c.create());
|
||||
QVERIFY(!o.isNull());
|
||||
auto lib = qobject_cast<SplitLib *>(o.get());
|
||||
QVERIFY(lib);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_splitlib)
|
||||
#include "tst_qmlsplitlib.moc"
|
Loading…
Reference in New Issue