Merge integration refs/builds/qtci/dev/1616744759

This commit is contained in:
Qt CI Bot 2021-03-26 10:09:36 +00:00
commit 27ebeeb50e
2 changed files with 58 additions and 13 deletions

View File

@ -127,23 +127,24 @@
Bindable properties must not be used as variables in algorithms. Each value written Bindable properties must not be used as variables in algorithms. Each value written
would be communicated to dependent properties. would be communicated to dependent properties.
For example, in the following code, other properties dependent on myProperty would be For example, in the following code, other properties that depend on
first informed about the change to 42, then about the change to maxvalue. \b myProperty would be first informed about the change to \b 42, then about
the change to \b maxValue.
\badcode \badcode
myProperty = somecomputation(); // returning, say, 42 myProperty = somecomputation(); // returning, say, 42
if (myProperty.value() > maxvalue) if (myProperty.value() > maxValue)
myProperty = maxvalue; myProperty = maxValue;
\endcode \endcode
Instead, perform the computation in a separate variable. Correct usage is shown in the Instead, perform the computation in a separate variable. Correct usage is shown in the
following example. following example.
\code \code
int newvalue = somecomputation(); int newValue = someComputation();
if (newvalue > maxvalue) if (newValue > maxValue)
newvalue = maxvalue; newValue = maxValue;
myProperty = newvalue; // only write to the property once myProperty = newValue; // only write to the property once
\endcode \endcode
\section2 Writing Bindable Properties in Transitional States \section2 Writing Bindable Properties in Transitional States
@ -153,13 +154,13 @@
not be written in transient states, when class invariants are not met. not be written in transient states, when class invariants are not met.
For example, in a class representing a circle which holds two members For example, in a class representing a circle which holds two members
"radius" and "area" consistent, a setter might look like this (where radius \b radius and \b area consistent, a setter might look like this (where radius
is a bindable property): is a bindable property):
\badcode \badcode
void setRadius(double newvalue) void setRadius(double newValue)
{ {
radius = newvalue; // this might trigger change handlers radius = newValue; // this might trigger change handlers
area = M_PI * radius * radius; area = M_PI * radius * radius;
emit radiusChanged(); emit radiusChanged();
} }
@ -168,6 +169,44 @@
Here, code triggered in change handlers might use the circle, while it has Here, code triggered in change handlers might use the circle, while it has
the new radius, but still the old area. the new radius, but still the old area.
\section1 Formulating a Property Binding
Any C++ expression evaluating to the correct type can be used as a binding
expression and be given to the setBinding() method. However, to formulate
a correct binding, some rules must be followed.
Dependency tracking only works on bindable properties. It's the developer's
responsibility to ensure that all properties used in the binding expression
are bindable properties. When non-bindable properties are used in a binding
expression, changes to those properties do not trigger updates to the bound
property. No warning or error is generated either at compile-time or at run-time.
The bound property will be updated only when bindable properties used in the
binding expression are changed.
Non-bindable properties might be used in a binding if it's possible
to ensure that markDirty is called on the property being bound on each
change of the non-bindable dependency.
The bound property might evaluate its binding several times during its lifetime.
The developer must make sure that all objects used in the binding expression
live longer than the binding.
The bindable property system is not thread-safe. Properties used in the binding
expression on one thread must not be read or modified by any other thread.
An object of a QObject-derived class which has a property with a binding must
not be moved to a different thread.
Also, an object of a QObject-derived class which has a property which is used
in a binding must not be moved to a different thread. In this context, it's
irrelevant whether it's used in a binding of a property in the same object
or in a binding of a property in another object.
The binding expression should not read from the property it's a binding for. Otherwise,
an evaluation loop exists.
The binding expression must not write to the property it's a binding for.
Functions used as bindings as well as all code which is called inside a binding
must not co_await. Doing so can confuse the property system's tracking of dependencies.
\section1 Tracking Bindable Properties \section1 Tracking Bindable Properties
Sometimes the relationships between properties cannot be expressed using Sometimes the relationships between properties cannot be expressed using

View File

@ -1042,6 +1042,8 @@ QString QPropertyBindingError::description() const
is read, the binding is evaluated by invoking the call operator () of \a f. is read, the binding is evaluated by invoking the call operator () of \a f.
Whenever a dependency of the binding changes, the binding will be re-evaluated Whenever a dependency of the binding changes, the binding will be re-evaluated
the next time the value of this property is read. the next time the value of this property is read.
\sa {Formulating a Property Binding}
*/ */
/*! /*!
@ -1441,6 +1443,8 @@ QString QPropertyBindingError::description() const
Whenever a dependency of the binding changes, the binding will be re-evaluated Whenever a dependency of the binding changes, the binding will be re-evaluated
the next time the value of this property is read. When the property value the next time the value of this property is read. When the property value
changes, the owner is notified via the Callback function. changes, the owner is notified via the Callback function.
\sa {Formulating a Property Binding}
*/ */
/*! /*!
@ -1667,6 +1671,8 @@ QString QPropertyBindingError::description() const
Returns any previous binding associated with the property, or a Returns any previous binding associated with the property, or a
default-constructed QPropertyBinding<T>. default-constructed QPropertyBinding<T>.
\sa {Formulating a Property Binding}
*/ */
/*! /*!