From d88b52b541a0482b69639dbea8976287db9ca52b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20De=20Canni=C3=A8re?= Date: Fri, 28 Apr 2023 11:08:02 +0200 Subject: Examples: Move Qml plugin example to manual tests Outdated documention has been removed. Task-number: QTBUG-111036 Change-Id: I8db138ff71615a6ed6ac4cebdb365c27252fa5ee Pick-to: 6.5 Reviewed-by: Ulf Hermann --- examples/qml/CMakeLists.txt | 1 - examples/qml/qml.pro | 5 -- examples/qml/qmlextensionplugins/CMakeLists.txt | 62 ---------------- .../doc/images/qml-plugins-example.png | Bin 15773 -> 0 bytes .../qmlextensionplugins/doc/src/qmlpluginex.qdoc | 43 ----------- .../imports/TimeExample/Clock.qml | 51 ------------- .../imports/TimeExample/center.png | Bin 765 -> 0 bytes .../imports/TimeExample/clock.png | Bin 20653 -> 0 bytes .../imports/TimeExample/hour.png | Bin 518 -> 0 bytes .../imports/TimeExample/minute.png | Bin 528 -> 0 bytes .../qmlextensionplugins/imports/TimeExample/qmldir | 3 - examples/qml/qmlextensionplugins/plugin.cpp | 15 ---- examples/qml/qmlextensionplugins/plugins.qml | 16 ---- .../qml/qmlextensionplugins/plugins.qmlproject | 18 ----- .../qmlextensionplugins/qmlextensionplugins.pro | 46 ------------ examples/qml/qmlextensionplugins/timemodel.cpp | 51 ------------- examples/qml/qmlextensionplugins/timemodel.h | 64 ---------------- .../modules/qqmlextensionplugin.qdocinc | 82 --------------------- tests/auto/quick/examples/tst_examples.cpp | 1 - tests/manual/CMakeLists.txt | 1 + tests/manual/qmlextensionplugins/CMakeLists.txt | 62 ++++++++++++++++ .../doc/images/qml-plugins-example.png | Bin 0 -> 15773 bytes .../qmlextensionplugins/doc/src/qmlpluginex.qdoc | 43 +++++++++++ .../imports/TimeExample/Clock.qml | 51 +++++++++++++ .../imports/TimeExample/center.png | Bin 0 -> 765 bytes .../imports/TimeExample/clock.png | Bin 0 -> 20653 bytes .../imports/TimeExample/hour.png | Bin 0 -> 518 bytes .../imports/TimeExample/minute.png | Bin 0 -> 528 bytes .../qmlextensionplugins/imports/TimeExample/qmldir | 3 + tests/manual/qmlextensionplugins/plugin.cpp | 15 ++++ tests/manual/qmlextensionplugins/plugins.qml | 16 ++++ .../manual/qmlextensionplugins/plugins.qmlproject | 18 +++++ .../qmlextensionplugins/qmlextensionplugins.pro | 46 ++++++++++++ tests/manual/qmlextensionplugins/timemodel.cpp | 51 +++++++++++++ tests/manual/qmlextensionplugins/timemodel.h | 64 ++++++++++++++++ 35 files changed, 370 insertions(+), 458 deletions(-) delete mode 100644 examples/qml/qmlextensionplugins/CMakeLists.txt delete mode 100644 examples/qml/qmlextensionplugins/doc/images/qml-plugins-example.png delete mode 100644 examples/qml/qmlextensionplugins/doc/src/qmlpluginex.qdoc delete mode 100644 examples/qml/qmlextensionplugins/imports/TimeExample/Clock.qml delete mode 100644 examples/qml/qmlextensionplugins/imports/TimeExample/center.png delete mode 100644 examples/qml/qmlextensionplugins/imports/TimeExample/clock.png delete mode 100644 examples/qml/qmlextensionplugins/imports/TimeExample/hour.png delete mode 100644 examples/qml/qmlextensionplugins/imports/TimeExample/minute.png delete mode 100644 examples/qml/qmlextensionplugins/imports/TimeExample/qmldir delete mode 100644 examples/qml/qmlextensionplugins/plugin.cpp delete mode 100644 examples/qml/qmlextensionplugins/plugins.qml delete mode 100644 examples/qml/qmlextensionplugins/plugins.qmlproject delete mode 100644 examples/qml/qmlextensionplugins/qmlextensionplugins.pro delete mode 100644 examples/qml/qmlextensionplugins/timemodel.cpp delete mode 100644 examples/qml/qmlextensionplugins/timemodel.h create mode 100644 tests/manual/qmlextensionplugins/CMakeLists.txt create mode 100644 tests/manual/qmlextensionplugins/doc/images/qml-plugins-example.png create mode 100644 tests/manual/qmlextensionplugins/doc/src/qmlpluginex.qdoc create mode 100644 tests/manual/qmlextensionplugins/imports/TimeExample/Clock.qml create mode 100644 tests/manual/qmlextensionplugins/imports/TimeExample/center.png create mode 100644 tests/manual/qmlextensionplugins/imports/TimeExample/clock.png create mode 100644 tests/manual/qmlextensionplugins/imports/TimeExample/hour.png create mode 100644 tests/manual/qmlextensionplugins/imports/TimeExample/minute.png create mode 100644 tests/manual/qmlextensionplugins/imports/TimeExample/qmldir create mode 100644 tests/manual/qmlextensionplugins/plugin.cpp create mode 100644 tests/manual/qmlextensionplugins/plugins.qml create mode 100644 tests/manual/qmlextensionplugins/plugins.qmlproject create mode 100644 tests/manual/qmlextensionplugins/qmlextensionplugins.pro create mode 100644 tests/manual/qmlextensionplugins/timemodel.cpp create mode 100644 tests/manual/qmlextensionplugins/timemodel.h diff --git a/examples/qml/CMakeLists.txt b/examples/qml/CMakeLists.txt index 331a4dcda4..b4abeb8a52 100644 --- a/examples/qml/CMakeLists.txt +++ b/examples/qml/CMakeLists.txt @@ -3,7 +3,6 @@ add_subdirectory(tutorials) if(TARGET Qt6::Quick) - qt_internal_add_example(qmlextensionplugins) if (TARGET Qt6::lupdate) qt_internal_add_example(qml-i18n) endif() diff --git a/examples/qml/qml.pro b/examples/qml/qml.pro index b59620cb81..e2da016924 100644 --- a/examples/qml/qml.pro +++ b/examples/qml/qml.pro @@ -1,11 +1,6 @@ TEMPLATE = subdirs QT_FOR_CONFIG += qml -qtHaveModule(quick) { - SUBDIRS += \ - qmlextensionplugins -} - SUBDIRS += \ tutorials diff --git a/examples/qml/qmlextensionplugins/CMakeLists.txt b/examples/qml/qmlextensionplugins/CMakeLists.txt deleted file mode 100644 index 26e454b0b4..0000000000 --- a/examples/qml/qmlextensionplugins/CMakeLists.txt +++ /dev/null @@ -1,62 +0,0 @@ -# Copyright (C) 2022 The Qt Company Ltd. -# SPDX-License-Identifier: BSD-3-Clause - -cmake_minimum_required(VERSION 3.16) -project(qmlqtimeexample LANGUAGES CXX) - -set(CMAKE_AUTOMOC ON) - -if(NOT DEFINED INSTALL_EXAMPLESDIR) - set(INSTALL_EXAMPLESDIR "examples") -endif() - -set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/qml/qmlextensionplugins/imports/TimeExample") - -find_package(Qt6 REQUIRED COMPONENTS Core Gui Qml) - -qt_standard_project_setup(REQUIRES 6.5) - -#![0] -set(qml_files - imports/TimeExample/Clock.qml -) - -set(images - imports/TimeExample/center.png - imports/TimeExample/clock.png - imports/TimeExample/hour.png - imports/TimeExample/minute.png -) -#![0] - -foreach(file IN LISTS qml_files images) - get_filename_component(filename ${file} NAME) - set_source_files_properties(${file} PROPERTIES QT_RESOURCE_ALIAS ${filename}) -endforeach() - -#![1] -qt_add_qml_module(qmlqtimeexample - OUTPUT_DIRECTORY imports/TimeExample - URI "TimeExample" - SOURCES timemodel.cpp timemodel.h - QML_FILES ${qml_files} - RESOURCES ${images} -) -#![1] - -set_target_properties(qmlqtimeexample PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) - -target_link_libraries(qmlqtimeexample PUBLIC - Qt6::Core - Qt6::Gui - Qt6::Qml -) - -install(TARGETS qmlqtimeexample - RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" - BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" - LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" -) diff --git a/examples/qml/qmlextensionplugins/doc/images/qml-plugins-example.png b/examples/qml/qmlextensionplugins/doc/images/qml-plugins-example.png deleted file mode 100644 index c2d4886ea2..0000000000 Binary files a/examples/qml/qmlextensionplugins/doc/images/qml-plugins-example.png and /dev/null differ diff --git a/examples/qml/qmlextensionplugins/doc/src/qmlpluginex.qdoc b/examples/qml/qmlextensionplugins/doc/src/qmlpluginex.qdoc deleted file mode 100644 index 80f39e36ce..0000000000 --- a/examples/qml/qmlextensionplugins/doc/src/qmlpluginex.qdoc +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (C) 2021 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only - -/*! - \title QML Plugin Example - \example qmlextensionplugins - - \brief This example creates a C++ plugin extension by subclassing QQmlEngineExtensionPlugin. - - \image qml-plugins-example.png - - To run this example, use the following commands on the prompt: - - \if defined(onlinedocs) - \tab {build-qt-app}{tab-cmake}{CMake}{checked} - \tab {build-qt-app}{tab-qmake}{qmake}{} - \tabcontent {tab-cmake} - \else - \section1 Using CMake - \endif - \badcode \QtVersion - cmake -DCMAKE_PREFIX_PATH=path/to/Qt/\1/your_platform -S -B -G Ninja - cd path/to/build/dir - ninja - qml -I imports plugins.qml - \endcode - For more information about building on the command line using CMake, - see \l {Building projects on the command line}. - \if defined(onlinedocs) - \endtabcontent - \tabcontent {tab-qmake} - \else - \section1 Using qmake - \endif - \badcode - qmake - make - qml -I imports plugins.qml - \endcode - \if defined(onlinedocs) - \endtabcontent - \endif -*/ diff --git a/examples/qml/qmlextensionplugins/imports/TimeExample/Clock.qml b/examples/qml/qmlextensionplugins/imports/TimeExample/Clock.qml deleted file mode 100644 index b071e2e031..0000000000 --- a/examples/qml/qmlextensionplugins/imports/TimeExample/Clock.qml +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (C) 2017 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause - -import QtQuick - -Rectangle { - id: clock - width: 200; height: 200; color: "gray" - - property alias city: cityLabel.text - property variant hours - property variant minutes - property variant shift : 0 - - Image { id: background; source: "clock.png" } - - Image { - x: 92.5; y: 27 - source: "hour.png" - transform: Rotation { - id: hourRotation - origin.x: 7.5; origin.y: 73; - angle: (clock.hours * 30) + (clock.minutes * 0.5) - Behavior on angle { - SpringAnimation{ spring: 2; damping: 0.2; modulus: 360 } - } - } - } - - Image { - x: 93.5; y: 17 - source: "minute.png" - transform: Rotation { - id: minuteRotation - origin.x: 6.5; origin.y: 83; - angle: clock.minutes * 6 - Behavior on angle { - SpringAnimation{ spring: 2; damping: 0.2; modulus: 360 } - } - } - } - - Image { - anchors.centerIn: background; source: "center.png" - } - - Text { - id: cityLabel; font.bold: true; font.pixelSize: 14; y:200; color: "white" - anchors.horizontalCenter: parent.horizontalCenter - } -} diff --git a/examples/qml/qmlextensionplugins/imports/TimeExample/center.png b/examples/qml/qmlextensionplugins/imports/TimeExample/center.png deleted file mode 100644 index 7fbd802a44..0000000000 Binary files a/examples/qml/qmlextensionplugins/imports/TimeExample/center.png and /dev/null differ diff --git a/examples/qml/qmlextensionplugins/imports/TimeExample/clock.png b/examples/qml/qmlextensionplugins/imports/TimeExample/clock.png deleted file mode 100644 index 462edacc0e..0000000000 Binary files a/examples/qml/qmlextensionplugins/imports/TimeExample/clock.png and /dev/null differ diff --git a/examples/qml/qmlextensionplugins/imports/TimeExample/hour.png b/examples/qml/qmlextensionplugins/imports/TimeExample/hour.png deleted file mode 100644 index 9f33fc5d48..0000000000 Binary files a/examples/qml/qmlextensionplugins/imports/TimeExample/hour.png and /dev/null differ diff --git a/examples/qml/qmlextensionplugins/imports/TimeExample/minute.png b/examples/qml/qmlextensionplugins/imports/TimeExample/minute.png deleted file mode 100644 index e2f216c897..0000000000 Binary files a/examples/qml/qmlextensionplugins/imports/TimeExample/minute.png and /dev/null differ diff --git a/examples/qml/qmlextensionplugins/imports/TimeExample/qmldir b/examples/qml/qmlextensionplugins/imports/TimeExample/qmldir deleted file mode 100644 index 252e662e12..0000000000 --- a/examples/qml/qmlextensionplugins/imports/TimeExample/qmldir +++ /dev/null @@ -1,3 +0,0 @@ -module TimeExample -Clock 1.0 Clock.qml -plugin qmlqtimeexampleplugin diff --git a/examples/qml/qmlextensionplugins/plugin.cpp b/examples/qml/qmlextensionplugins/plugin.cpp deleted file mode 100644 index 066d284a5e..0000000000 --- a/examples/qml/qmlextensionplugins/plugin.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (C) 2017 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause - -#include -#include - -//![plugin] -class QExampleQmlPlugin : public QQmlEngineExtensionPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid) -}; -//![plugin] - -#include "plugin.moc" diff --git a/examples/qml/qmlextensionplugins/plugins.qml b/examples/qml/qmlextensionplugins/plugins.qml deleted file mode 100644 index 55e8903400..0000000000 --- a/examples/qml/qmlextensionplugins/plugins.qml +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2017 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -//![0] -import TimeExample // import types from the plugin - -Clock { // this class is defined in QML (imports/TimeExample/Clock.qml) - - Time { // this class is defined in C++ (plugin.cpp) - id: time - } - - hours: time.hour - minutes: time.minute - -} -//![0] diff --git a/examples/qml/qmlextensionplugins/plugins.qmlproject b/examples/qml/qmlextensionplugins/plugins.qmlproject deleted file mode 100644 index c2de5f5703..0000000000 --- a/examples/qml/qmlextensionplugins/plugins.qmlproject +++ /dev/null @@ -1,18 +0,0 @@ -import QmlProject 1.1 - -Project { - mainFile: "plugins.qml" - - /* Include .qml, .js, and image files from current directory and subdirectories */ - QmlFiles { - directory: "." - } - JavaScriptFiles { - directory: "." - } - ImageFiles { - directory: "." - } - - importPaths: [ "imports" ] -} diff --git a/examples/qml/qmlextensionplugins/qmlextensionplugins.pro b/examples/qml/qmlextensionplugins/qmlextensionplugins.pro deleted file mode 100644 index c074b8d671..0000000000 --- a/examples/qml/qmlextensionplugins/qmlextensionplugins.pro +++ /dev/null @@ -1,46 +0,0 @@ -TEMPLATE = lib -CONFIG += plugin qmltypes -QT += qml - -QML_IMPORT_NAME = TimeExample -QML_IMPORT_MAJOR_VERSION = 1 - -DESTDIR = imports/$$QML_IMPORT_NAME -TARGET = qmlqtimeexampleplugin -QMLTYPES_FILENAME = $$DESTDIR/plugins.qmltypes - -SOURCES += \ - plugin.cpp \ - timemodel.cpp - -HEADERS += \ - timemodel.h - -PLUGINFILES = \ - imports/$$QML_IMPORT_NAME/qmldir \ - imports/$$QML_IMPORT_NAME/center.png \ - imports/$$QML_IMPORT_NAME/clock.png \ - imports/$$QML_IMPORT_NAME/Clock.qml \ - imports/$$QML_IMPORT_NAME/hour.png \ - imports/$$QML_IMPORT_NAME/minute.png - -target.path = $$[QT_INSTALL_EXAMPLES]/qml/qmlextensionplugins/imports/$$QML_IMPORT_NAME - -pluginfiles_copy.files = $$PLUGINFILES -pluginfiles_copy.path = $$DESTDIR - -pluginfiles_install.files = $$PLUGINFILES $$OUT_PWD/$$DESTDIR/plugins.qmltypes -pluginfiles_install.path = $$[QT_INSTALL_EXAMPLES]/qml/qmlextensionplugins/imports/$$QML_IMPORT_NAME - -qml_copy.files = plugins.qml plugins.qmlproject -qml_copy.path = $$OUT_PWD - -qml_install.files = plugins.qml plugins.qmlproject -qml_install.path = $$[QT_INSTALL_EXAMPLES]/qml/qmlextensionplugins - -INSTALLS += target qml_install pluginfiles_install -COPIES += qml_copy pluginfiles_copy - -OTHER_FILES += $$PLUGINFILES plugins.qml - -CONFIG += install_ok # Do not cargo-cult this! diff --git a/examples/qml/qmlextensionplugins/timemodel.cpp b/examples/qml/qmlextensionplugins/timemodel.cpp deleted file mode 100644 index a94a7e773d..0000000000 --- a/examples/qml/qmlextensionplugins/timemodel.cpp +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (C) 2017 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause - -#include "timemodel.h" - -int TimeModel::instances=0; -MinuteTimer *TimeModel::timer=nullptr; - -void MinuteTimer::start() -{ - if (!timer.isActive()) { - time = QTime::currentTime(); - timer.start(60000-time.second()*1000, this); - } -} - -void MinuteTimer::stop() -{ - timer.stop(); -} - -void MinuteTimer::timerEvent(QTimerEvent *) -{ - QTime now = QTime::currentTime(); - if (now.second() == 59 && now.minute() == time.minute() && now.hour() == time.hour()) { - // just missed time tick over, force it, wait extra 0.5 seconds - time = time.addSecs(60); - timer.start(60500, this); - } else { - time = now; - timer.start(60000-time.second()*1000, this); - } - emit timeChanged(); -} - -TimeModel::TimeModel(QObject *parent) : QObject(parent) -{ - if (++instances == 1) { - if (!timer) - timer = new MinuteTimer(QCoreApplication::instance()); - connect(timer, &MinuteTimer::timeChanged, this, &TimeModel::timeChanged); - timer->start(); - } -} - -TimeModel::~TimeModel() -{ - if (--instances == 0) { - timer->stop(); - } -} diff --git a/examples/qml/qmlextensionplugins/timemodel.h b/examples/qml/qmlextensionplugins/timemodel.h deleted file mode 100644 index 2c27a6dada..0000000000 --- a/examples/qml/qmlextensionplugins/timemodel.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (C) 2017 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause - -#ifndef TIMEMODEL_H -#define TIMEMODEL_H - -#include -#include -#include -#include - -// Implements a "TimeModel" class with hour and minute properties -// that change on-the-minute yet efficiently sleep the rest -// of the time. - -class MinuteTimer : public QObject -{ - Q_OBJECT -public: - MinuteTimer(QObject *parent) : QObject(parent) {} - - void start(); - void stop(); - - int hour() const { return time.hour(); } - int minute() const { return time.minute(); } - -signals: - void timeChanged(); - -protected: - void timerEvent(QTimerEvent *) override; - -private: - QTime time; - QBasicTimer timer; -}; - -//![0] -class TimeModel : public QObject -{ - Q_OBJECT - Q_PROPERTY(int hour READ hour NOTIFY timeChanged) - Q_PROPERTY(int minute READ minute NOTIFY timeChanged) - QML_NAMED_ELEMENT(Time) -//![0] - -public: - TimeModel(QObject *parent=nullptr); - ~TimeModel() override; - - int minute() const { return timer->minute(); } - int hour() const { return timer->hour(); } - -signals: - void timeChanged(); - -private: - QTime t; - static MinuteTimer *timer; - static int instances; -}; - -#endif // TIMEMODEL_H diff --git a/src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc b/src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc index fca702a278..771d520f8a 100644 --- a/src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc +++ b/src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc @@ -62,85 +62,3 @@ that's part of the same binary as the registration: volatile auto registration = &qml_register_types_my_module; Q_UNUSED(registration); \endcode - -\section1 TimeExample QML Extension Plugin - -Suppose there is a new \c TimeModel C++ class that should be made available -as a new QML type. It provides the current time through \c hour and \c minute -properties. It declares a QML type called \c Time via \l QML_NAMED_ELEMENT(). - -\snippet qmlextensionplugins/timemodel.h 0 -\dots - -To make this type available, create a plugin class named \c QExampleQmlPlugin, -which is a subclass of \l QQmlEngineExtensionPlugin. It uses the -Q_PLUGIN_METADATA() macro in the class definition to register the plugin with -the Qt meta object system using a unique identifier for the plugin. - -\snippet qmlextensionplugins/plugin.cpp plugin - -\section1 Build Settings for the Plugin - -The build file defines the project as a plugin library, specifies it should be -built into the \c imports/TimeExample directory, and registers the plugin -target name. - -\section2 Using CMake: - -\snippet qmlextensionplugins/CMakeLists.txt 0 - -\snippet qmlextensionplugins/CMakeLists.txt 1 - -\section2 Using qmake: - -\code -TEMPLATE = lib -CONFIG += qt plugin qmltypes -QT += qml - -QML_IMPORT_NAME = TimeExample -QML_IMPORT_MAJOR_VERSION = 1 - -DESTDIR = imports/$$QML_IMPORT_NAME -TARGET = qmlqtimeexampleplugin - -SOURCES += qexampleqmlplugin.cpp -\endcode - -This registers the \c TimeModel class, with the import \c{TimeExample 1.0}, as -a QML type called \c Time. The \l{Defining QML Types from C++} article has more -information about registering C++ types for usage in QML. - -\section1 Plugin Definition in the qmldir - -Finally, a \l {Module Definition qmldir Files} {qmldir file} is required -in the \c imports/TimeExample directory to describe the plugin and the types -that it exports. The plugin includes a \c Clock.qml file along with the -\c qmlqtimeexampleplugin that is built by the project. - -CMake will, by default, automatically generate this file. For more -information, see \l {Auto-generating qmldir and typeinfo files}. - -When using qmake, specify the following in the \c qmldir file: - -\quotefile qmlextensionplugins/imports/TimeExample/qmldir - -To make things easier for this example, the TimeExample source directory is in -\c{imports/TimeExample}, and we build -\l{Source, Build, and Install Directories}{in-source}. However, the structure -of the source directory is not important, as the \c qmldir file can specify -paths to installed QML files. - -What is important is the name of the directory that the qmldir is installed -into. When the user imports our module, the QML engine uses the -\l{Contents of a Module Definition qmldir File}{module identifier} -(\c TimeExample) to find the plugin, so the directory in which it is -installed must match the module identifier. - -Once the project is built and installed, the new \c Time component is -accessible by any QML component that imports the \c TimeExample -module. - -\snippet qmlextensionplugins/plugins.qml 0 - -The full source code is available in the \l {qmlextensionplugins}{plugins example}. diff --git a/tests/auto/quick/examples/tst_examples.cpp b/tests/auto/quick/examples/tst_examples.cpp index de27fe92cb..76b67f9a04 100644 --- a/tests/auto/quick/examples/tst_examples.cpp +++ b/tests/auto/quick/examples/tst_examples.cpp @@ -54,7 +54,6 @@ tst_examples::tst_examples() // Add directories you want excluded here excludedDirs << "shared"; //Not an example excludedDirs << "snippets/qml/path"; //No root QQuickItem - excludedDirs << "examples/qml/qmlextensionplugins"; //Requires special import search path // These snippets are not expected to run on their own. excludedDirs << "snippets/qml/visualdatamodel_rootindex"; diff --git a/tests/manual/CMakeLists.txt b/tests/manual/CMakeLists.txt index 0d45a56c4e..48d0adae75 100644 --- a/tests/manual/CMakeLists.txt +++ b/tests/manual/CMakeLists.txt @@ -20,3 +20,4 @@ add_subdirectory(frameanimation) if(QT_FEATURE_qml_network AND TARGET Qt::Quick) add_subdirectory(networkaccessmanagerfactory) endif() +add_subdirectory(qmlextensionplugins) diff --git a/tests/manual/qmlextensionplugins/CMakeLists.txt b/tests/manual/qmlextensionplugins/CMakeLists.txt new file mode 100644 index 0000000000..26e454b0b4 --- /dev/null +++ b/tests/manual/qmlextensionplugins/CMakeLists.txt @@ -0,0 +1,62 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(qmlqtimeexample LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/qml/qmlextensionplugins/imports/TimeExample") + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Qml) + +qt_standard_project_setup(REQUIRES 6.5) + +#![0] +set(qml_files + imports/TimeExample/Clock.qml +) + +set(images + imports/TimeExample/center.png + imports/TimeExample/clock.png + imports/TimeExample/hour.png + imports/TimeExample/minute.png +) +#![0] + +foreach(file IN LISTS qml_files images) + get_filename_component(filename ${file} NAME) + set_source_files_properties(${file} PROPERTIES QT_RESOURCE_ALIAS ${filename}) +endforeach() + +#![1] +qt_add_qml_module(qmlqtimeexample + OUTPUT_DIRECTORY imports/TimeExample + URI "TimeExample" + SOURCES timemodel.cpp timemodel.h + QML_FILES ${qml_files} + RESOURCES ${images} +) +#![1] + +set_target_properties(qmlqtimeexample PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +target_link_libraries(qmlqtimeexample PUBLIC + Qt6::Core + Qt6::Gui + Qt6::Qml +) + +install(TARGETS qmlqtimeexample + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/tests/manual/qmlextensionplugins/doc/images/qml-plugins-example.png b/tests/manual/qmlextensionplugins/doc/images/qml-plugins-example.png new file mode 100644 index 0000000000..c2d4886ea2 Binary files /dev/null and b/tests/manual/qmlextensionplugins/doc/images/qml-plugins-example.png differ diff --git a/tests/manual/qmlextensionplugins/doc/src/qmlpluginex.qdoc b/tests/manual/qmlextensionplugins/doc/src/qmlpluginex.qdoc new file mode 100644 index 0000000000..80f39e36ce --- /dev/null +++ b/tests/manual/qmlextensionplugins/doc/src/qmlpluginex.qdoc @@ -0,0 +1,43 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \title QML Plugin Example + \example qmlextensionplugins + + \brief This example creates a C++ plugin extension by subclassing QQmlEngineExtensionPlugin. + + \image qml-plugins-example.png + + To run this example, use the following commands on the prompt: + + \if defined(onlinedocs) + \tab {build-qt-app}{tab-cmake}{CMake}{checked} + \tab {build-qt-app}{tab-qmake}{qmake}{} + \tabcontent {tab-cmake} + \else + \section1 Using CMake + \endif + \badcode \QtVersion + cmake -DCMAKE_PREFIX_PATH=path/to/Qt/\1/your_platform -S -B -G Ninja + cd path/to/build/dir + ninja + qml -I imports plugins.qml + \endcode + For more information about building on the command line using CMake, + see \l {Building projects on the command line}. + \if defined(onlinedocs) + \endtabcontent + \tabcontent {tab-qmake} + \else + \section1 Using qmake + \endif + \badcode + qmake + make + qml -I imports plugins.qml + \endcode + \if defined(onlinedocs) + \endtabcontent + \endif +*/ diff --git a/tests/manual/qmlextensionplugins/imports/TimeExample/Clock.qml b/tests/manual/qmlextensionplugins/imports/TimeExample/Clock.qml new file mode 100644 index 0000000000..b071e2e031 --- /dev/null +++ b/tests/manual/qmlextensionplugins/imports/TimeExample/Clock.qml @@ -0,0 +1,51 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick + +Rectangle { + id: clock + width: 200; height: 200; color: "gray" + + property alias city: cityLabel.text + property variant hours + property variant minutes + property variant shift : 0 + + Image { id: background; source: "clock.png" } + + Image { + x: 92.5; y: 27 + source: "hour.png" + transform: Rotation { + id: hourRotation + origin.x: 7.5; origin.y: 73; + angle: (clock.hours * 30) + (clock.minutes * 0.5) + Behavior on angle { + SpringAnimation{ spring: 2; damping: 0.2; modulus: 360 } + } + } + } + + Image { + x: 93.5; y: 17 + source: "minute.png" + transform: Rotation { + id: minuteRotation + origin.x: 6.5; origin.y: 83; + angle: clock.minutes * 6 + Behavior on angle { + SpringAnimation{ spring: 2; damping: 0.2; modulus: 360 } + } + } + } + + Image { + anchors.centerIn: background; source: "center.png" + } + + Text { + id: cityLabel; font.bold: true; font.pixelSize: 14; y:200; color: "white" + anchors.horizontalCenter: parent.horizontalCenter + } +} diff --git a/tests/manual/qmlextensionplugins/imports/TimeExample/center.png b/tests/manual/qmlextensionplugins/imports/TimeExample/center.png new file mode 100644 index 0000000000..7fbd802a44 Binary files /dev/null and b/tests/manual/qmlextensionplugins/imports/TimeExample/center.png differ diff --git a/tests/manual/qmlextensionplugins/imports/TimeExample/clock.png b/tests/manual/qmlextensionplugins/imports/TimeExample/clock.png new file mode 100644 index 0000000000..462edacc0e Binary files /dev/null and b/tests/manual/qmlextensionplugins/imports/TimeExample/clock.png differ diff --git a/tests/manual/qmlextensionplugins/imports/TimeExample/hour.png b/tests/manual/qmlextensionplugins/imports/TimeExample/hour.png new file mode 100644 index 0000000000..9f33fc5d48 Binary files /dev/null and b/tests/manual/qmlextensionplugins/imports/TimeExample/hour.png differ diff --git a/tests/manual/qmlextensionplugins/imports/TimeExample/minute.png b/tests/manual/qmlextensionplugins/imports/TimeExample/minute.png new file mode 100644 index 0000000000..e2f216c897 Binary files /dev/null and b/tests/manual/qmlextensionplugins/imports/TimeExample/minute.png differ diff --git a/tests/manual/qmlextensionplugins/imports/TimeExample/qmldir b/tests/manual/qmlextensionplugins/imports/TimeExample/qmldir new file mode 100644 index 0000000000..252e662e12 --- /dev/null +++ b/tests/manual/qmlextensionplugins/imports/TimeExample/qmldir @@ -0,0 +1,3 @@ +module TimeExample +Clock 1.0 Clock.qml +plugin qmlqtimeexampleplugin diff --git a/tests/manual/qmlextensionplugins/plugin.cpp b/tests/manual/qmlextensionplugins/plugin.cpp new file mode 100644 index 0000000000..066d284a5e --- /dev/null +++ b/tests/manual/qmlextensionplugins/plugin.cpp @@ -0,0 +1,15 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include +#include + +//![plugin] +class QExampleQmlPlugin : public QQmlEngineExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid) +}; +//![plugin] + +#include "plugin.moc" diff --git a/tests/manual/qmlextensionplugins/plugins.qml b/tests/manual/qmlextensionplugins/plugins.qml new file mode 100644 index 0000000000..55e8903400 --- /dev/null +++ b/tests/manual/qmlextensionplugins/plugins.qml @@ -0,0 +1,16 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +//![0] +import TimeExample // import types from the plugin + +Clock { // this class is defined in QML (imports/TimeExample/Clock.qml) + + Time { // this class is defined in C++ (plugin.cpp) + id: time + } + + hours: time.hour + minutes: time.minute + +} +//![0] diff --git a/tests/manual/qmlextensionplugins/plugins.qmlproject b/tests/manual/qmlextensionplugins/plugins.qmlproject new file mode 100644 index 0000000000..c2de5f5703 --- /dev/null +++ b/tests/manual/qmlextensionplugins/plugins.qmlproject @@ -0,0 +1,18 @@ +import QmlProject 1.1 + +Project { + mainFile: "plugins.qml" + + /* Include .qml, .js, and image files from current directory and subdirectories */ + QmlFiles { + directory: "." + } + JavaScriptFiles { + directory: "." + } + ImageFiles { + directory: "." + } + + importPaths: [ "imports" ] +} diff --git a/tests/manual/qmlextensionplugins/qmlextensionplugins.pro b/tests/manual/qmlextensionplugins/qmlextensionplugins.pro new file mode 100644 index 0000000000..c074b8d671 --- /dev/null +++ b/tests/manual/qmlextensionplugins/qmlextensionplugins.pro @@ -0,0 +1,46 @@ +TEMPLATE = lib +CONFIG += plugin qmltypes +QT += qml + +QML_IMPORT_NAME = TimeExample +QML_IMPORT_MAJOR_VERSION = 1 + +DESTDIR = imports/$$QML_IMPORT_NAME +TARGET = qmlqtimeexampleplugin +QMLTYPES_FILENAME = $$DESTDIR/plugins.qmltypes + +SOURCES += \ + plugin.cpp \ + timemodel.cpp + +HEADERS += \ + timemodel.h + +PLUGINFILES = \ + imports/$$QML_IMPORT_NAME/qmldir \ + imports/$$QML_IMPORT_NAME/center.png \ + imports/$$QML_IMPORT_NAME/clock.png \ + imports/$$QML_IMPORT_NAME/Clock.qml \ + imports/$$QML_IMPORT_NAME/hour.png \ + imports/$$QML_IMPORT_NAME/minute.png + +target.path = $$[QT_INSTALL_EXAMPLES]/qml/qmlextensionplugins/imports/$$QML_IMPORT_NAME + +pluginfiles_copy.files = $$PLUGINFILES +pluginfiles_copy.path = $$DESTDIR + +pluginfiles_install.files = $$PLUGINFILES $$OUT_PWD/$$DESTDIR/plugins.qmltypes +pluginfiles_install.path = $$[QT_INSTALL_EXAMPLES]/qml/qmlextensionplugins/imports/$$QML_IMPORT_NAME + +qml_copy.files = plugins.qml plugins.qmlproject +qml_copy.path = $$OUT_PWD + +qml_install.files = plugins.qml plugins.qmlproject +qml_install.path = $$[QT_INSTALL_EXAMPLES]/qml/qmlextensionplugins + +INSTALLS += target qml_install pluginfiles_install +COPIES += qml_copy pluginfiles_copy + +OTHER_FILES += $$PLUGINFILES plugins.qml + +CONFIG += install_ok # Do not cargo-cult this! diff --git a/tests/manual/qmlextensionplugins/timemodel.cpp b/tests/manual/qmlextensionplugins/timemodel.cpp new file mode 100644 index 0000000000..a94a7e773d --- /dev/null +++ b/tests/manual/qmlextensionplugins/timemodel.cpp @@ -0,0 +1,51 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "timemodel.h" + +int TimeModel::instances=0; +MinuteTimer *TimeModel::timer=nullptr; + +void MinuteTimer::start() +{ + if (!timer.isActive()) { + time = QTime::currentTime(); + timer.start(60000-time.second()*1000, this); + } +} + +void MinuteTimer::stop() +{ + timer.stop(); +} + +void MinuteTimer::timerEvent(QTimerEvent *) +{ + QTime now = QTime::currentTime(); + if (now.second() == 59 && now.minute() == time.minute() && now.hour() == time.hour()) { + // just missed time tick over, force it, wait extra 0.5 seconds + time = time.addSecs(60); + timer.start(60500, this); + } else { + time = now; + timer.start(60000-time.second()*1000, this); + } + emit timeChanged(); +} + +TimeModel::TimeModel(QObject *parent) : QObject(parent) +{ + if (++instances == 1) { + if (!timer) + timer = new MinuteTimer(QCoreApplication::instance()); + connect(timer, &MinuteTimer::timeChanged, this, &TimeModel::timeChanged); + timer->start(); + } +} + +TimeModel::~TimeModel() +{ + if (--instances == 0) { + timer->stop(); + } +} diff --git a/tests/manual/qmlextensionplugins/timemodel.h b/tests/manual/qmlextensionplugins/timemodel.h new file mode 100644 index 0000000000..2c27a6dada --- /dev/null +++ b/tests/manual/qmlextensionplugins/timemodel.h @@ -0,0 +1,64 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef TIMEMODEL_H +#define TIMEMODEL_H + +#include +#include +#include +#include + +// Implements a "TimeModel" class with hour and minute properties +// that change on-the-minute yet efficiently sleep the rest +// of the time. + +class MinuteTimer : public QObject +{ + Q_OBJECT +public: + MinuteTimer(QObject *parent) : QObject(parent) {} + + void start(); + void stop(); + + int hour() const { return time.hour(); } + int minute() const { return time.minute(); } + +signals: + void timeChanged(); + +protected: + void timerEvent(QTimerEvent *) override; + +private: + QTime time; + QBasicTimer timer; +}; + +//![0] +class TimeModel : public QObject +{ + Q_OBJECT + Q_PROPERTY(int hour READ hour NOTIFY timeChanged) + Q_PROPERTY(int minute READ minute NOTIFY timeChanged) + QML_NAMED_ELEMENT(Time) +//![0] + +public: + TimeModel(QObject *parent=nullptr); + ~TimeModel() override; + + int minute() const { return timer->minute(); } + int hour() const { return timer->hour(); } + +signals: + void timeChanged(); + +private: + QTime t; + static MinuteTimer *timer; + static int instances; +}; + +#endif // TIMEMODEL_H -- cgit v1.2.1