diff options
author | Luca Di Sera <luca.disera@qt.io> | 2024-03-11 16:33:35 +0100 |
---|---|---|
committer | Luca Di Sera <luca.disera@qt.io> | 2024-03-20 16:59:30 +0100 |
commit | 361b601620073351013b516e9f7cf9f5173b9ce7 (patch) | |
tree | 8a46f93f4349dfe8dc64493834def517bf2daa8c /src/qml/doc/snippets | |
parent | cf15ba9b085ac783fd3315f1b103c012947cb7db (diff) |
qmltc: Allow setting initial values when creating a compiled type
`qmltc`-generated types currently do not allow setting any initial
values for the property of a component during creation.
For example, some component `Foo` with a property `bar`, will have no
way to set `bar` to a specific value from the C++ side of the code
before an instance of `Foo` is obtained by the user.
This lack of control prohibits the user from interacting with certain
processes that are part of the component creation.
For example, if a component provides am `onCompleted` binding that
depends on some of the values of its properties, the user is inhibited
from varying the per-instance values that `onCompleted` depends on, as
the user would be able to vary those values only after the component is
created and the `onCompleted` signal is emitted.
This differs, from example, from the `QQmlComponent` interface, where
the user is able to provide some initialization values as part of
the creation of an instance of the component.
To allow the user to have more control in the initialization of the
instance of a component, before it is fully created, `qmltc` generated
code now allows the user to provide an initialization callback that is
processed as part of the creation cycle of an instance of the component.
The callback provides the user with a generated proxy object,
`PropertyInitializer`, that only knows how to set the writable,
non-private properties of the component.
The generated code for the public constructor of a `qmltc`-generated
type was modified to provide an optional `initializer` parameter that
stores the callback.
The private `QML_init` method that `qmltc` generates for each type, that
performs the required setup to create an instance of a component, was
modified to allow for the same optional parameter, which is passed on by
the public constructor.
The body of `QML_init` was modified to call the new parameter, after
having performed the general set-up for the created instance but before
the instance is completed and before setting up "complex bindings" such
as an `onPropertyChanged` handler.
The callback is called with an instance of the generated proxy object
that is built on-site.
The proxy-object keeps track of the properties that were actually
initialized by the callback. This information is now passed down to
`QML_setComplexBindings`, which avoids setting up any unnecessary
bindings for the properties that were initialized.
A representation for the proxy object was added to the internal IR that
is used by `qmltc` when generating code.
The representation for a compiled C++ type was modified to store an
instance of the proxy object.
The newly stored instance is now populated as part of the general
compilation of a type, by the `compilePropertyInitializer` free-function
in "qmltccompiler.cpp".
The component responsible for the final code-generation,
`QmltcCodeWriter`, was modified to be able to generate code for the new
proxy object representation.
The documentation for `QmltcCodeGenerator::generate_initCode`, which
sets up the body for `QML_init`, was updated to reflect the new body.
A pre-existing issue in the documentation of the method, which failed to
enumerate all generated steps for the body, was fixed as part of the
change.
The preamble that `qmltc` generates for all generated header files
was modified to include "QtCore/qxpfunction.h", to have access to
`qxp::function_ref`, which is used to store the new callback parameter.
A pre-existing snapshot test had its snapshot file,
"src/qml/doc/snippets/qmltc/special/HelloWorld.qml.cpp", updated to
reflect the changes to the generated code.
A new basic, non-exhaustive test case was added to the
available corpus of `qmltc` tests to test the basic workflow of
providing an initialization callback.
The documentation for `qmltc` was modified to mention the new parameter.
Task-number: QTBUG-120700
Change-Id: I246c1c3634982580d66b31fd891382559a9cc3ae
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/doc/snippets')
-rw-r--r-- | src/qml/doc/snippets/qmltc/special/HelloWorld.qml.cpp | 2 | ||||
-rw-r--r-- | src/qml/doc/snippets/qmltc/tst_qmltc_examples.cpp | 5 |
2 files changed, 5 insertions, 2 deletions
diff --git a/src/qml/doc/snippets/qmltc/special/HelloWorld.qml.cpp b/src/qml/doc/snippets/qmltc/special/HelloWorld.qml.cpp index eda9009bb7..0afbcbf0bf 100644 --- a/src/qml/doc/snippets/qmltc/special/HelloWorld.qml.cpp +++ b/src/qml/doc/snippets/qmltc/special/HelloWorld.qml.cpp @@ -22,7 +22,7 @@ class HelloWorld : public QObject Q_PROPERTY(QString hello WRITE setHello READ hello BINDABLE bindableHello) public: - HelloWorld(QQmlEngine* engine, QObject* parent = nullptr); + HelloWorld(QQmlEngine* engine, QObject* parent = nullptr, [[maybe_unused]] qxp::function_ref<void(PropertyInitializer&)> initializer = [](PropertyInitializer&){}); Q_SIGNALS: void created(); diff --git a/src/qml/doc/snippets/qmltc/tst_qmltc_examples.cpp b/src/qml/doc/snippets/qmltc/tst_qmltc_examples.cpp index 7bda70f985..8c2706531b 100644 --- a/src/qml/doc/snippets/qmltc/tst_qmltc_examples.cpp +++ b/src/qml/doc/snippets/qmltc/tst_qmltc_examples.cpp @@ -53,7 +53,10 @@ void tst_qmltc_examples::app() QQmlEngine e; QQuickWindow window; - QScopedPointer<QmltcExample::myApp> documentRoot(new QmltcExample::myApp(&e)); + QScopedPointer<QmltcExample::myApp> documentRoot( + new QmltcExample::myApp(&e, nullptr, [](auto& component){ + component.setWidth(800); + })); documentRoot->setParentItem(window.contentItem()); window.setHeight(documentRoot->height()); |