QObjectBindableProperty: Allow signals taking a value
If the signal takes a value, we pass the current value of the property to it. As we now use eager evaluation, accessing the current value is now possible. Change-Id: I5e6947a6575bfa8ca5143f56620c645d4750a686 Reviewed-by: Andreas Buhr <andreas.buhr@qt.io> Reviewed-by: Ivan Solovev <ivan.solovev@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
parent
d558ebf79b
commit
cdabe1d64c
@ -1344,6 +1344,10 @@ QString QPropertyBindingError::description() const
|
||||
|
||||
\snippet code/src_corelib_kernel_qproperty.cpp 2
|
||||
|
||||
The change handler can optionally accept one argument, of the same type as the property,
|
||||
in which case it is passed the new value of the property. Otherwise, it should take no
|
||||
arguments.
|
||||
|
||||
If the property does not need a changed notification, you can leave out the
|
||||
"NOTIFY xChanged" in the Q_PROPERTY macro as well as the last argument
|
||||
of the Q_OBJECT_BINDABLE_PROPERTY and Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS
|
||||
|
@ -884,6 +884,7 @@ class QObjectBindableProperty : public QPropertyData<T>
|
||||
{
|
||||
using ThisType = QObjectBindableProperty<Class, T, Offset, Signal>;
|
||||
static bool constexpr HasSignal = !std::is_same_v<decltype(Signal), std::nullptr_t>;
|
||||
using SignalTakesValue = std::is_invocable<decltype(Signal), Class, T>;
|
||||
Class *owner()
|
||||
{
|
||||
char *that = reinterpret_cast<char *>(this);
|
||||
@ -897,9 +898,13 @@ class QObjectBindableProperty : public QPropertyData<T>
|
||||
static void signalCallBack(QUntypedPropertyData *o)
|
||||
{
|
||||
QObjectBindableProperty *that = static_cast<QObjectBindableProperty *>(o);
|
||||
if constexpr (HasSignal)
|
||||
if constexpr (HasSignal) {
|
||||
if constexpr (SignalTakesValue::value)
|
||||
(that->owner()->*Signal)(that->valueBypassingBindings());
|
||||
else
|
||||
(that->owner()->*Signal)();
|
||||
}
|
||||
}
|
||||
public:
|
||||
using value_type = typename QPropertyData<T>::value_type;
|
||||
using parameter_type = typename QPropertyData<T>::parameter_type;
|
||||
@ -1060,9 +1065,13 @@ private:
|
||||
{
|
||||
if (binding)
|
||||
binding->notifyObservers(this);
|
||||
if constexpr (HasSignal)
|
||||
if constexpr (HasSignal) {
|
||||
if constexpr (SignalTakesValue::value)
|
||||
(owner()->*Signal)(this->valueBypassingBindings());
|
||||
else
|
||||
(owner()->*Signal)();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#define Q_OBJECT_BINDABLE_PROPERTY3(Class, Type, name) \
|
||||
|
@ -83,6 +83,7 @@ private slots:
|
||||
void quntypedBindableApi();
|
||||
void readonlyConstQBindable();
|
||||
void qobjectBindableManualNotify();
|
||||
void qobjectBindableSignalTakingNewValue();
|
||||
|
||||
void testNewStuff();
|
||||
void qobjectObservers();
|
||||
@ -1088,7 +1089,7 @@ class MyQObject : public QObject
|
||||
Q_PROPERTY(int compat READ compat WRITE setCompat NOTIFY compatChanged)
|
||||
|
||||
signals:
|
||||
void fooChanged();
|
||||
void fooChanged(int newFoo);
|
||||
void barChanged();
|
||||
void compatChanged();
|
||||
|
||||
@ -1182,6 +1183,28 @@ void tst_QProperty::qobjectBindableManualNotify()
|
||||
QCOMPARE(object.foo(), 1);
|
||||
}
|
||||
|
||||
void tst_QProperty::qobjectBindableSignalTakingNewValue()
|
||||
{
|
||||
// Given an object of type MyQObject,
|
||||
MyQObject object;
|
||||
// and tracking the values emitted via its fooChanged signal,
|
||||
int newValue = -1;
|
||||
QObject::connect(&object, &MyQObject::fooChanged, [&](int i){ newValue = i; } );
|
||||
|
||||
// when we change the property's value via the bindable interface
|
||||
object.bindableFoo().setValue(1);
|
||||
// we obtain the newly set value.
|
||||
QCOMPARE(newValue, 1);
|
||||
|
||||
// The same holds true when we set a binding
|
||||
QProperty<int> i {2};
|
||||
object.bindableFoo().setBinding(Qt::makePropertyBinding(i));
|
||||
QCOMPARE(newValue, 2);
|
||||
// and when the binding gets reevaluated to a new value
|
||||
i = 3;
|
||||
QCOMPARE(newValue, 3);
|
||||
}
|
||||
|
||||
void tst_QProperty::testNewStuff()
|
||||
{
|
||||
MyQObject testReadOnly;
|
||||
|
Loading…
x
Reference in New Issue
Block a user