diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2021-04-23 14:51:40 +0200 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2021-05-03 20:32:42 +0200 |
commit | ba561efa9d4e94032e7b546e92a3dc66c06bec52 (patch) | |
tree | c6e1e1f06a43d18b845d492ae6af5117fec25bbe /src | |
parent | 98b4f4bc4d87aa2f2c30adbcb8fd42abcc88d6fb (diff) |
Add QUntypedBindable::metaType function
This enables checking the metaType of a QUntypedBindable in the public
interface.
In addition, work around an oversight that can only be fully addressed
in Qt 7: The metatype function pointer does not take a
QUntypedPropertyData * parameter. However, we need this functionality
for an efficient QBindable proxy implementation in declarative (which is
needed to implement interceptors there). To work-aronud this in Qt 6,
reuse the value getter and turn it into a metatype getter if the value
pointer is flagged.
Change-Id: Ia3cce08ea761fce57bce59e02212525b996f2fee
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/kernel/qproperty.cpp | 10 | ||||
-rw-r--r-- | src/corelib/kernel/qproperty.h | 25 |
2 files changed, 31 insertions, 4 deletions
diff --git a/src/corelib/kernel/qproperty.cpp b/src/corelib/kernel/qproperty.cpp index 607048d94b..a1b2f83c5b 100644 --- a/src/corelib/kernel/qproperty.cpp +++ b/src/corelib/kernel/qproperty.cpp @@ -1006,6 +1006,16 @@ QString QPropertyBindingError::description() const */ /*! + \fn QMetaType QUntypedBindable::metaType() const + \since 6.2 + + Returns the metatype of the property from which the QUntypedBindable was created. + If the bindable is invalid, an invalid metatype will be returned. + + \sa isValid(), QUntypedPropertyBinding::valueMetaType() +*/ + +/*! \class QBindable \inmodule QtCore \brief QBindable is a wrapper class around binding-enabled properties. It allows type-safe diff --git a/src/corelib/kernel/qproperty.h b/src/corelib/kernel/qproperty.h index 9be10c0a31..7924049698 100644 --- a/src/corelib/kernel/qproperty.h +++ b/src/corelib/kernel/qproperty.h @@ -484,6 +484,8 @@ struct QBindableInterface MakeBinding makeBinding; SetObserver setObserver; GetMetaType metaType; + + static constexpr quintptr MetaTypeAccessorFlag = 0x1; }; template<typename Property, typename = void> @@ -650,9 +652,9 @@ public: #endif return false; } - if (!binding.isNull() && binding.valueMetaType() != iface->metaType()) { + if (!binding.isNull() && binding.valueMetaType() != metaType()) { #ifndef QT_NO_DEBUG - QtPrivate::BindableWarnings::printMetaTypeMismatch(iface->metaType(), binding.valueMetaType()); + QtPrivate::BindableWarnings::printMetaTypeMismatch(metaType(), binding.valueMetaType()); #endif return false; } @@ -664,6 +666,21 @@ public: return !binding().isNull(); } + QMetaType metaType() const + { + if (!(iface && data)) + return QMetaType(); + if (iface->metaType) + return iface->metaType(); + // ### Qt 7: Change the metatype function to take data as its argument + // special casing for QML's proxy bindable: allow multiplexing in the getter + // function to retrieve the metatype from data + Q_ASSERT(iface->getter); + QMetaType result; + iface->getter(data, reinterpret_cast<void *>(quintptr(&result) | QtPrivate::QBindableInterface::MetaTypeAccessorFlag)); + return result; + } + }; template<typename T> @@ -678,7 +695,7 @@ public: using QUntypedBindable::QUntypedBindable; explicit QBindable(const QUntypedBindable &b) : QUntypedBindable(b) { - if (iface && iface->metaType() != QMetaType::fromType<T>()) { + if (iface && metaType() != QMetaType::fromType<T>()) { data = nullptr; iface = nullptr; } @@ -701,7 +718,7 @@ public: using QUntypedBindable::setBinding; QPropertyBinding<T> setBinding(const QPropertyBinding<T> &binding) { - Q_ASSERT(!iface || binding.isNull() || binding.valueMetaType() == iface->metaType()); + Q_ASSERT(!iface || binding.isNull() || binding.valueMetaType() == metaType()); if (iface && iface->setBinding) return static_cast<QPropertyBinding<T> &&>(iface->setBinding(data, binding)); |