Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qproperty.h
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#ifndef QPROPERTY_H
6#define QPROPERTY_H
7
8#include <QtCore/qglobal.h>
9#include <QtCore/qshareddata.h>
10#include <QtCore/qstring.h>
11#include <QtCore/qttypetraits.h>
12#include <QtCore/qbindingstorage.h>
13
14#include <type_traits>
15
16#include <QtCore/qpropertyprivate.h>
17
18#if __has_include(<source_location>) && __cplusplus >= 202002L && !defined(Q_QDOC)
19#include <source_location>
20#if defined(__cpp_lib_source_location)
21#define QT_SOURCE_LOCATION_NAMESPACE std
22#define QT_PROPERTY_COLLECT_BINDING_LOCATION
23#if defined(Q_CC_MSVC)
24/* MSVC runs into an issue with constexpr with source location (error C7595)
25 so use the factory function as a workaround */
26# define QT_PROPERTY_DEFAULT_BINDING_LOCATION QPropertyBindingSourceLocation::fromStdSourceLocation(std::source_location::current())
27#else
28/* some versions of gcc in turn run into
29 expression ‘std::source_location::current()’ is not a constant expression
30 so don't use the workaround there */
31# define QT_PROPERTY_DEFAULT_BINDING_LOCATION QPropertyBindingSourceLocation(std::source_location::current())
32#endif
33#endif
34#endif
35
36#if __has_include(<experimental/source_location>) && !defined(Q_QDOC)
37#include <experimental/source_location>
38#if !defined(QT_PROPERTY_COLLECT_BINDING_LOCATION)
39#if defined(__cpp_lib_experimental_source_location)
40#define QT_SOURCE_LOCATION_NAMESPACE std::experimental
41#define QT_PROPERTY_COLLECT_BINDING_LOCATION
42#define QT_PROPERTY_DEFAULT_BINDING_LOCATION QPropertyBindingSourceLocation(std::experimental::source_location::current())
43#endif // defined(__cpp_lib_experimental_source_location)
44#endif
45#endif
46
47#if !defined(QT_PROPERTY_COLLECT_BINDING_LOCATION)
48#define QT_PROPERTY_DEFAULT_BINDING_LOCATION QPropertyBindingSourceLocation()
49#endif
50
51QT_BEGIN_NAMESPACE
52
53namespace Qt {
54Q_CORE_EXPORT void beginPropertyUpdateGroup();
55Q_CORE_EXPORT void endPropertyUpdateGroup();
56}
57
68
69template <typename T>
71{
72protected:
73 mutable T val = T();
74private:
75 class DisableRValueRefs {};
76protected:
77 static constexpr bool UseReferences = !(std::is_arithmetic_v<T> || std::is_enum_v<T> || std::is_pointer_v<T>);
78public:
79 using value_type = T;
84
85 QPropertyData() = default;
86 QPropertyData(parameter_type t) : val(t) {}
87 QPropertyData(rvalue_ref t) : val(std::move(t)) {}
88 ~QPropertyData() = default;
89
91 void setValueBypassingBindings(parameter_type v) { val = v; }
92 void setValueBypassingBindings(rvalue_ref v) { val = std::move(v); }
93};
94
95// ### Qt 7: un-export
97{
98 const char *fileName = nullptr;
99 const char *functionName = nullptr;
100 quint32 line = 0;
101 quint32 column = 0;
102 QPropertyBindingSourceLocation() = default;
103#ifdef __cpp_lib_source_location
104 constexpr QPropertyBindingSourceLocation(const std::source_location &cppLocation)
105 {
106 fileName = cppLocation.file_name();
107 functionName = cppLocation.function_name();
108 line = cppLocation.line();
109 column = cppLocation.column();
110 }
111 QT_POST_CXX17_API_IN_EXPORTED_CLASS
112 static consteval QPropertyBindingSourceLocation
113 fromStdSourceLocation(const std::source_location &cppLocation)
114 {
115 return cppLocation;
116 }
117#endif
118#ifdef __cpp_lib_experimental_source_location
119 constexpr QPropertyBindingSourceLocation(const std::experimental::source_location &cppLocation)
120 {
121 fileName = cppLocation.file_name();
122 functionName = cppLocation.function_name();
123 line = cppLocation.line();
124 column = cppLocation.column();
125 }
126#endif
127};
128
129template <typename Functor> class QPropertyChangeHandler;
131
132class Q_CORE_EXPORT QPropertyBindingError
133{
134public:
135 enum Type {
136 NoError,
137 BindingLoop,
138 EvaluationError,
139 UnknownError
140 };
141
142 QPropertyBindingError();
143 QPropertyBindingError(Type type, const QString &description = QString());
144
145 QPropertyBindingError(const QPropertyBindingError &other);
146 QPropertyBindingError &operator=(const QPropertyBindingError &other);
147 QPropertyBindingError(QPropertyBindingError &&other);
148 QPropertyBindingError &operator=(QPropertyBindingError &&other);
149 ~QPropertyBindingError();
150
151 bool hasError() const { return d.get() != nullptr; }
152 Type type() const;
153 QString description() const;
154
155private:
156 QSharedDataPointer<QPropertyBindingErrorPrivate> d;
157};
158
159class Q_CORE_EXPORT QUntypedPropertyBinding
160{
161public:
162 // writes binding result into dataPtr
163 using BindingFunctionVTable = QtPrivate::BindingFunctionVTable;
164
165 QUntypedPropertyBinding();
166 QUntypedPropertyBinding(QMetaType metaType, const BindingFunctionVTable *vtable, void *function, const QPropertyBindingSourceLocation &location);
167
168 template<typename Functor>
169 QUntypedPropertyBinding(QMetaType metaType, Functor &&f, const QPropertyBindingSourceLocation &location)
170 : QUntypedPropertyBinding(metaType, &QtPrivate::bindingFunctionVTable<std::remove_reference_t<Functor>>, &f, location)
171 {}
172
173 QUntypedPropertyBinding(QUntypedPropertyBinding &&other);
174 QUntypedPropertyBinding(const QUntypedPropertyBinding &other);
175 QUntypedPropertyBinding &operator=(const QUntypedPropertyBinding &other);
176 QUntypedPropertyBinding &operator=(QUntypedPropertyBinding &&other);
177 ~QUntypedPropertyBinding();
178
179 bool isNull() const;
180
181 QPropertyBindingError error() const;
182
183 QMetaType valueMetaType() const;
184
185 explicit QUntypedPropertyBinding(QPropertyBindingPrivate *priv);
186private:
187 friend class QtPrivate::QPropertyBindingData;
188 friend class QPropertyBindingPrivate;
189 template <typename> friend class QPropertyBinding;
190 QPropertyBindingPrivatePtr d;
191};
192
193template <typename PropertyType>
195{
196
197public:
198 QPropertyBinding() = default;
199
200 template<typename Functor>
201 QPropertyBinding(Functor &&f, const QPropertyBindingSourceLocation &location)
203 {}
204
205
206 // Internal
207 explicit QPropertyBinding(const QUntypedPropertyBinding &binding)
209 {}
210};
211
212namespace Qt {
213 template <typename Functor>
214 auto makePropertyBinding(Functor &&f, const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION,
215 std::enable_if_t<std::is_invocable_v<Functor>> * = nullptr)
216 {
217 return QPropertyBinding<std::invoke_result_t<Functor>>(std::forward<Functor>(f), location);
218 }
219}
220
221struct QPropertyObserverPrivate;
223class QPropertyObserver;
224
226{
227public:
228 // Internal
230 ObserverNotifiesBinding, // observer was installed to notify bindings that obsverved property changed
231 ObserverNotifiesChangeHandler, // observer is a change handler, which runs on every change
232 ObserverIsPlaceholder, // the observer before this one is currently evaluated in QPropertyObserver::notifyObservers.
233#if QT_DEPRECATED_SINCE(6, 6)
234 ObserverIsAlias QT_DEPRECATED_VERSION_X_6_6("Use QProperty and add a binding to the target.")
235#endif
236 };
237protected:
238 using ChangeHandler = void (*)(QPropertyObserver*, QUntypedPropertyData *);
239
240private:
243 friend class QPropertyObserver;
246 friend class QPropertyBindingPrivate;
247
248 QTaggedPointer<QPropertyObserver, ObserverTag> next;
249 // prev is a pointer to the "next" element within the previous node, or to the "firstObserverPtr" if it is the
250 // first node.
251 QtPrivate::QTagPreservingPointerToPointer<QPropertyObserver, ObserverTag> prev;
252
253 union {
257 };
258};
259
260class Q_CORE_EXPORT QPropertyObserver : public QPropertyObserverBase
261{
262public:
263 constexpr QPropertyObserver() = default;
264 QPropertyObserver(QPropertyObserver &&other) noexcept;
265 QPropertyObserver &operator=(QPropertyObserver &&other) noexcept;
266 ~QPropertyObserver();
267
268 template <typename Property, QtPrivate::IsUntypedPropertyData<Property> = true>
269 void setSource(const Property &property)
270 { setSource(property.bindingData()); }
271 void setSource(const QtPrivate::QPropertyBindingData &property);
272
273protected:
274 QPropertyObserver(ChangeHandler changeHandler);
275#if QT_DEPRECATED_SINCE(6, 6)
276 QT_DEPRECATED_VERSION_X_6_6("This constructor was only meant for internal use. Use QProperty and add a binding to the target.")
277 QPropertyObserver(QUntypedPropertyData *aliasedPropertyPtr);
278#endif
279
280 QUntypedPropertyData *aliasedProperty() const
281 {
282 return aliasData;
283 }
284
285private:
286
287 QPropertyObserver(const QPropertyObserver &) = delete;
288 QPropertyObserver &operator=(const QPropertyObserver &) = delete;
289
290};
291
292template <typename Functor>
319
321{
322 std::function<void()> m_handler;
323public:
325 QPropertyNotifier() = default;
326 template<typename Functor>
336
337 template <typename Functor, typename Property,
349};
350
351template <typename T>
352class QProperty : public QPropertyData<T>
353{
354 QtPrivate::QPropertyBindingData d;
355 bool is_equal(const T &v)
356 {
357 if constexpr (QTypeTraits::has_operator_equal_v<T>) {
358 if (v == this->val)
359 return true;
360 }
361 return false;
362 }
363
364 template <typename U, typename = void>
365 struct has_operator_equal_to : std::false_type{};
366
367 template <typename U>
368 struct has_operator_equal_to<U, std::void_t<decltype(bool(std::declval<const T&>() == std::declval<const U&>()))>>
369 : std::true_type{};
370
371 template <typename U>
372 static constexpr bool has_operator_equal_to_v =
374
375public:
376 using value_type = typename QPropertyData<T>::value_type;
378 using rvalue_ref = typename QPropertyData<T>::rvalue_ref;
380
381 QProperty() = default;
382 explicit QProperty(parameter_type initialValue) : QPropertyData<T>(initialValue) {}
383 explicit QProperty(rvalue_ref initialValue) : QPropertyData<T>(std::move(initialValue)) {}
384 explicit QProperty(const QPropertyBinding<T> &binding)
385 : QProperty()
386 { setBinding(binding); }
387#ifndef Q_QDOC
388 template <typename Functor>
389 explicit QProperty(Functor &&f, const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION,
390 typename std::enable_if_t<std::is_invocable_r_v<T, Functor&>> * = nullptr)
391 : QProperty(QPropertyBinding<T>(std::forward<Functor>(f), location))
392 {}
393#else
394 template <typename Functor>
395 explicit QProperty(Functor &&f);
396#endif
397 ~QProperty() = default;
398
399 QT_DECLARE_EQUALITY_OPERATORS_HELPER(QProperty, QProperty, /* non-constexpr */, noexcept(false), template <typename Ty = T, std::enable_if_t<QTypeTraits::has_operator_equal_v<Ty>>* = nullptr>)
400 QT_DECLARE_EQUALITY_OPERATORS_HELPER(QProperty, T, /* non-constexpr */, noexcept(false), template <typename Ty = T, std::enable_if_t<QTypeTraits::has_operator_equal_v<Ty>>* = nullptr>)
401 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(QProperty, T, /* non-constexpr */, noexcept(false), template <typename Ty = T, std::enable_if_t<QTypeTraits::has_operator_equal_v<Ty>>* = nullptr>)
402
403 QT_DECLARE_EQUALITY_OPERATORS_HELPER(QProperty, U, /* non-constexpr */, noexcept(false), template <typename U, std::enable_if_t<has_operator_equal_to_v<U>>* = nullptr>)
404 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(QProperty, U, /* non-constexpr */, noexcept(false), template <typename U, std::enable_if_t<has_operator_equal_to_v<U>>* = nullptr>)
405
406 // Explicitly delete op==(QProperty<T>, QProperty<U>) for different T & U.
407 // We do not want implicit conversions here!
408 // However, GCC complains about using a default template argument in a
409 // friend declaration, while Clang and MSVC are fine. So, skip GCC here.
410#if !defined(Q_CC_GNU) || defined(Q_CC_CLANG)
411#define QPROPERTY_DECL_DELETED_EQ_OP
412 Q_DECL_EQ_DELETE_X("Call .value() on one of the properties explicitly.")
413 template <typename U, std::enable_if_t<!std::is_same_v<T, U>>* = nullptr>
415 template <typename U, std::enable_if_t<!std::is_same_v<T, U>>* = nullptr>
416 friend void operator!=(const QProperty &, const QProperty<U> &) QPROPERTY_DECL_DELETED_EQ_OP;
417#undef QPROPERTY_DECL_DELETED_EQ_OP
418#endif // !defined(Q_CC_GNU) || defined(Q_CC_CLANG)
419
421 {
422 d.registerWithCurrentlyEvaluatingBinding();
423 return this->val;
424 }
425
427 {
428 if constexpr (QTypeTraits::is_dereferenceable_v<T>) {
429 return value();
430 } else if constexpr (std::is_pointer_v<T>) {
431 value();
432 return this->val;
433 } else {
434 return;
435 }
436 }
437
439 {
440 return value();
441 }
442
444 {
445 return value();
446 }
447
448 void setValue(rvalue_ref newValue)
449 {
450 d.removeBinding();
451 if (is_equal(newValue))
452 return;
453 this->val = std::move(newValue);
454 notify();
455 }
456
458 {
459 d.removeBinding();
460 if (is_equal(newValue))
461 return;
462 this->val = newValue;
463 notify();
464 }
465
467 {
468 setValue(std::move(newValue));
469 return *this;
470 }
471
473 {
474 setValue(newValue);
475 return *this;
476 }
477
479 {
480 return QPropertyBinding<T>(d.setBinding(newBinding, this));
481 }
482
483 bool setBinding(const QUntypedPropertyBinding &newBinding)
484 {
485 if (!newBinding.isNull() && newBinding.valueMetaType().id() != qMetaTypeId<T>())
486 return false;
487 setBinding(static_cast<const QPropertyBinding<T> &>(newBinding));
488 return true;
489 }
490
491#ifndef Q_QDOC
492 template <typename Functor>
494 const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION,
495 std::enable_if_t<std::is_invocable_v<Functor>> * = nullptr)
496 {
497 return setBinding(Qt::makePropertyBinding(std::forward<Functor>(f), location));
498 }
499#else
500 template <typename Functor>
502#endif
503
504 bool hasBinding() const { return d.hasBinding(); }
505
507 {
508 return QPropertyBinding<T>(QUntypedPropertyBinding(d.binding()));
509 }
510
512 {
513 return QPropertyBinding<T>(d.setBinding(QUntypedPropertyBinding(), this));
514 }
515
516 template<typename Functor>
518 {
519 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
520 return QPropertyChangeHandler<Functor>(*this, std::move(f));
521 }
522
523 template<typename Functor>
525 {
526 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
527 f();
528 return onValueChanged(std::move(f));
529 }
530
531 template<typename Functor>
533 {
534 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
535 return QPropertyNotifier(*this, std::move(f));
536 }
537
538 const QtPrivate::QPropertyBindingData &bindingData() const { return d; }
539private:
540 template <typename Ty = T, std::enable_if_t<QTypeTraits::has_operator_equal_v<Ty>>* = nullptr>
541 friend bool comparesEqual(const QProperty &lhs, const QProperty &rhs)
542 {
543 return lhs.value() == rhs.value();
544 }
545
546 template <typename Ty = T, std::enable_if_t<QTypeTraits::has_operator_equal_v<Ty>>* = nullptr>
547 friend bool comparesEqual(const QProperty &lhs, const T &rhs)
548 {
549 return lhs.value() == rhs;
550 }
551
552 template <typename U, std::enable_if_t<has_operator_equal_to_v<U>>* = nullptr>
553 friend bool comparesEqual(const QProperty &lhs, const U &rhs)
554 {
555 return lhs.value() == rhs;
556 }
557
558 void notify()
559 {
560 d.notifyObservers(this);
561 }
562
564};
565
566namespace Qt {
567 template <typename PropertyType>
568 QPropertyBinding<PropertyType> makePropertyBinding(const QProperty<PropertyType> &otherProperty,
569 const QPropertyBindingSourceLocation &location =
571 {
572 return Qt::makePropertyBinding([&otherProperty]() -> PropertyType { return otherProperty; }, location);
573 }
574}
575
576
577namespace QtPrivate
578{
579
581{
582 using Getter = void (*)(const QUntypedPropertyData *d, void *value);
583 using Setter = void (*)(QUntypedPropertyData *d, const void *value);
587 using SetObserver = void (*)(const QUntypedPropertyData *d, QPropertyObserver *observer);
588 using GetMetaType = QMetaType (*)();
596
597 static constexpr quintptr MetaTypeAccessorFlag = 0x1;
598};
599
600template<typename Property, typename = void>
602{
603 using T = typename Property::value_type;
604public:
605 // interface for computed properties. Those do not have a binding()/setBinding() method, but one can
606 // install observers on them.
607 static constexpr QBindableInterface iface = {
608 [](const QUntypedPropertyData *d, void *value) -> void
609 { *static_cast<T*>(value) = static_cast<const Property *>(d)->value(); },
610 nullptr,
611 nullptr,
612 nullptr,
614 { return Qt::makePropertyBinding([d]() -> T { return static_cast<const Property *>(d)->value(); }, location); },
616 { observer->setSource(static_cast<const Property *>(d)->bindingData()); },
617 []() { return QMetaType::fromType<T>(); }
618 };
619};
620
621template<typename Property>
623{
624 using T = typename Property::value_type;
625public:
626 // A bindable created from a const property results in a read-only interface, too.
627 static constexpr QBindableInterface iface = {
628
629 [](const QUntypedPropertyData *d, void *value) -> void
630 { *static_cast<T*>(value) = static_cast<const Property *>(d)->value(); },
631 /*setter=*/nullptr,
633 { return static_cast<const Property *>(d)->binding(); },
634 /*setBinding=*/nullptr,
636 { return Qt::makePropertyBinding([d]() -> T { return static_cast<const Property *>(d)->value(); }, location); },
638 { observer->setSource(static_cast<const Property *>(d)->bindingData()); },
639 []() { return QMetaType::fromType<T>(); }
640 };
641};
642
643template<typename Property>
645{
646 using T = typename Property::value_type;
647public:
648 static constexpr QBindableInterface iface = {
649 [](const QUntypedPropertyData *d, void *value) -> void
650 { *static_cast<T*>(value) = static_cast<const Property *>(d)->value(); },
651 [](QUntypedPropertyData *d, const void *value) -> void
652 { static_cast<Property *>(d)->setValue(*static_cast<const T*>(value)); },
654 { return static_cast<const Property *>(d)->binding(); },
656 { return static_cast<Property *>(d)->setBinding(static_cast<const QPropertyBinding<T> &>(binding)); },
658 { return Qt::makePropertyBinding([d]() -> T { return static_cast<const Property *>(d)->value(); }, location); },
660 { observer->setSource(static_cast<const Property *>(d)->bindingData()); },
661 []() { return QMetaType::fromType<T>(); }
662 };
663};
664
665}
666
667namespace QtPrivate {
668// used in Q(Untyped)Bindable to print warnings about various binding errors
669namespace BindableWarnings {
671Q_CORE_EXPORT void printUnsuitableBindableWarning(QAnyStringView prefix, Reason reason);
672Q_CORE_EXPORT void printMetaTypeMismatch(QMetaType actual, QMetaType expected);
673}
674
676Q_CORE_EXPORT void getter(const QUntypedPropertyData *d, void *value);
677Q_CORE_EXPORT void setter(QUntypedPropertyData *d, const void *value);
678Q_CORE_EXPORT QUntypedPropertyBinding getBinding(const QUntypedPropertyData *d);
679Q_CORE_EXPORT bool bindingWrapper(QMetaType type, QUntypedPropertyData *d,
680 QtPrivate::QPropertyBindingFunction binding,
681 QUntypedPropertyData *temp, void *value);
682Q_CORE_EXPORT QUntypedPropertyBinding setBinding(QUntypedPropertyData *d,
685Q_CORE_EXPORT void setObserver(const QUntypedPropertyData *d, QPropertyObserver *observer);
686
687template<typename T>
688bool bindingWrapper(QMetaType type, QUntypedPropertyData *d,
689 QtPrivate::QPropertyBindingFunction binding)
690{
691 struct Data : QPropertyData<T>
692 {
693 void *data() { return &this->val; }
694 } temp;
695 return bindingWrapper(type, d, binding, &temp, temp.data());
696}
697
698template<typename T>
699QUntypedPropertyBinding setBinding(QUntypedPropertyData *d, const QUntypedPropertyBinding &binding)
700{
701 return setBinding(d, binding, &bindingWrapper<T>);
702}
703
704template<typename T>
705QUntypedPropertyBinding makeBinding(const QUntypedPropertyData *d,
706 const QPropertyBindingSourceLocation &location)
707{
708 return Qt::makePropertyBinding(
709 [d]() -> T {
710 T r;
711 getter(d, &r);
712 return r;
713 },
714 location);
715}
716
717template<class T>
718inline constexpr QBindableInterface iface = {
719#ifdef QT_NO_DATA_RELOCATION
720 // On windows the address of a dllimported function can't be relocated here.
721 // MSVC automatically generates a trampoline, but clang won't, so do it explicitly.
722 [](const QUntypedPropertyData *d, void *value) { getter(d, value); },
723 [](QUntypedPropertyData *d, const void *value) { setter(d, value); },
724 [](const QUntypedPropertyData *d) -> QUntypedPropertyBinding { return getBinding(d); },
725 &setBinding<T>,
726 &makeBinding<T>,
729#else
730 &getter,
731 &setter,
732 &getBinding,
733 &setBinding<T>,
734 &makeBinding<T>,
737#endif
738};
739}
740}
741
743{
744 friend struct QUntypedBindablePrivate; // allows access to internal data
745protected:
748 constexpr QUntypedBindable(QUntypedPropertyData *d, const QtPrivate::QBindableInterface *i)
749 : data(d), iface(i)
750 {}
751
754
755public:
756 constexpr QUntypedBindable() = default;
757 template<typename Property>
758 QUntypedBindable(Property *p)
759 : data(const_cast<std::remove_cv_t<Property> *>(p)),
761 { Q_ASSERT(data && iface); }
762
763 bool isValid() const { return data != nullptr; }
764 bool isBindable() const { return iface && iface->getBinding; }
765 bool isReadOnly() const { return !(iface && iface->setBinding && iface->setObserver); }
766
767 QUntypedPropertyBinding makeBinding(const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION) const
768 {
769 return iface ? iface->makeBinding(data, location) : QUntypedPropertyBinding();
770 }
771
773 {
774 if (!iface)
775 return QUntypedPropertyBinding {};
776 // We do not have a dedicated takeBinding function pointer in the interface
777 // therefore we synthesize takeBinding by retrieving the binding with binding
778 // and calling setBinding with a default constructed QUntypedPropertyBinding
779 // afterwards.
780 if (!(iface->getBinding && iface->setBinding))
781 return QUntypedPropertyBinding {};
782 return [&] {
783 QUntypedPropertyBinding binding = iface->getBinding(data);
784 iface->setBinding(data, QUntypedPropertyBinding{});
785 return binding;
786 }();
787 }
788
789 void observe(QPropertyObserver *observer) const
790 {
791 if (iface)
792 iface->setObserver(data, observer);
793#ifndef QT_NO_DEBUG
794 else
797#endif
798 }
799
800 template<typename Functor>
801 QPropertyChangeHandler<Functor> onValueChanged(Functor f) const
802 {
803 QPropertyChangeHandler<Functor> handler(std::move(f));
804 observe(&handler);
805 return handler;
806 }
807
808 template<typename Functor>
809 QPropertyChangeHandler<Functor> subscribe(Functor f) const
810 {
811 f();
812 return onValueChanged(std::move(f));
813 }
814
815 template<typename Functor>
817 {
818 QPropertyNotifier handler(std::move(f));
819 observe(&handler);
820 return handler;
821 }
822
824 {
825 if (!isBindable()) {
826#ifndef QT_NO_DEBUG
829#endif
830 return QUntypedPropertyBinding();
831 }
832 return iface->getBinding(data);
833 }
834 bool setBinding(const QUntypedPropertyBinding &binding)
835 {
836 if (isReadOnly()) {
837#ifndef QT_NO_DEBUG
840 QtPrivate::BindableWarnings::printUnsuitableBindableWarning("setBinding: Could not set binding via bindable interface.", errorType);
841#endif
842 return false;
843 }
844 if (!binding.isNull() && binding.valueMetaType() != metaType()) {
845#ifndef QT_NO_DEBUG
846 QtPrivate::BindableWarnings::printMetaTypeMismatch(metaType(), binding.valueMetaType());
847#endif
848 return false;
849 }
850 iface->setBinding(data, binding);
851 return true;
852 }
853 bool hasBinding() const
854 {
855 return !binding().isNull();
856 }
857
859 {
860 if (!(iface && data))
861 return QMetaType();
862 if (iface->metaType)
863 return iface->metaType();
864 // ### Qt 7: Change the metatype function to take data as its argument
865 // special casing for QML's proxy bindable: allow multiplexing in the getter
866 // function to retrieve the metatype from data
867 Q_ASSERT(iface->getter);
868 QMetaType result;
869 iface->getter(data, reinterpret_cast<void *>(quintptr(&result) | QtPrivate::QBindableInterface::MetaTypeAccessorFlag));
870 return result;
871 }
872
873};
874
875template<typename T>
876class QBindable : public QUntypedBindable
877{
878 template<typename U>
879 friend class QPropertyAlias;
880 constexpr QBindable(QUntypedPropertyData *d, const QtPrivate::QBindableInterface *i)
881 : QUntypedBindable(d, i)
882 {}
883public:
884 using QUntypedBindable::QUntypedBindable;
886 {
887 if (iface && metaType() != QMetaType::fromType<T>()) {
888 data = nullptr;
889 iface = nullptr;
890 }
891 }
892
893 explicit QBindable(QObject *obj, const QMetaProperty &property)
894 : QUntypedBindable(obj, property, &QtPrivate::PropertyAdaptorSlotObjectHelpers::iface<T>) {}
895
896 explicit QBindable(QObject *obj, const char *property)
897 : QUntypedBindable(obj, property, &QtPrivate::PropertyAdaptorSlotObjectHelpers::iface<T>) {}
898
899 QPropertyBinding<T> makeBinding(const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION) const
900 {
901 return static_cast<QPropertyBinding<T> &&>(QUntypedBindable::makeBinding(location));
902 }
904 {
905 return static_cast<QPropertyBinding<T> &&>(QUntypedBindable::binding());
906 }
907
909 {
910 return static_cast<QPropertyBinding<T> &&>(QUntypedBindable::takeBinding());
911 }
912
913 using QUntypedBindable::setBinding;
915 {
916 Q_ASSERT(!iface || binding.isNull() || binding.valueMetaType() == metaType());
917
918 if (iface && iface->setBinding)
919 return static_cast<QPropertyBinding<T> &&>(iface->setBinding(data, binding));
920#ifndef QT_NO_DEBUG
921 if (!iface)
923 else
925#endif
926 return QPropertyBinding<T>();
927 }
928#ifndef Q_QDOC
929 template <typename Functor>
931 const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION,
932 std::enable_if_t<std::is_invocable_v<Functor>> * = nullptr)
933 {
934 return setBinding(Qt::makePropertyBinding(std::forward<Functor>(f), location));
935 }
936#else
937 template <typename Functor>
938 QPropertyBinding<T> setBinding(Functor f);
939#endif
940
941 T value() const
942 {
943 if (iface) {
944 T result;
945 iface->getter(data, &result);
946 return result;
947 }
948 return T{};
949 }
950
951 void setValue(const T &value)
952 {
953 if (iface && iface->setter)
954 iface->setter(data, &value);
955 }
956};
957
958#if QT_DEPRECATED_SINCE(6, 6)
959template<typename T>
960class QT_DEPRECATED_VERSION_X_6_6("Class was only meant for internal use, use a QProperty and add a binding to the target")
961QPropertyAlias : public QPropertyObserver
962{
963 Q_DISABLE_COPY_MOVE(QPropertyAlias)
964 const QtPrivate::QBindableInterface *iface = nullptr;
965
966public:
967 QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
968 QPropertyAlias(QProperty<T> *property)
969 : QPropertyObserver(property),
970 iface(&QtPrivate::QBindableInterfaceForProperty<QProperty<T>>::iface)
971 {
972 if (iface)
973 iface->setObserver(aliasedProperty(), this);
974 }
975
976 template <typename Property, QtPrivate::IsUntypedPropertyData<Property> = true>
977 QPropertyAlias(Property *property)
978 : QPropertyObserver(property),
979 iface(&QtPrivate::QBindableInterfaceForProperty<Property>::iface)
980 {
981 if (iface)
982 iface->setObserver(aliasedProperty(), this);
983 }
984
985 QPropertyAlias(QPropertyAlias<T> *alias)
986 : QPropertyObserver(alias->aliasedProperty()),
987 iface(alias->iface)
988 {
989 if (iface)
990 iface->setObserver(aliasedProperty(), this);
991 }
992
993 QPropertyAlias(const QBindable<T> &property)
994 : QPropertyObserver(property.data),
995 iface(property.iface)
996 {
997 if (iface)
998 iface->setObserver(aliasedProperty(), this);
999 }
1000
1001 T value() const
1002 {
1003 T t = T();
1004 if (auto *p = aliasedProperty())
1005 iface->getter(p, &t);
1006 return t;
1007 }
1008
1009 operator T() const { return value(); }
1010
1011 void setValue(const T &newValue)
1012 {
1013 if (auto *p = aliasedProperty())
1014 iface->setter(p, &newValue);
1015 }
1016
1017 QPropertyAlias<T> &operator=(const T &newValue)
1018 {
1019 setValue(newValue);
1020 return *this;
1021 }
1022
1023 QPropertyBinding<T> setBinding(const QPropertyBinding<T> &newBinding)
1024 {
1025 return QBindable<T>(aliasedProperty(), iface).setBinding(newBinding);
1026 }
1027
1028 bool setBinding(const QUntypedPropertyBinding &newBinding)
1029 {
1030 return QBindable<T>(aliasedProperty(), iface).setBinding(newBinding);
1031 }
1032
1033#ifndef Q_QDOC
1034 template <typename Functor>
1035 QPropertyBinding<T> setBinding(Functor &&f,
1036 const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION,
1037 std::enable_if_t<std::is_invocable_v<Functor>> * = nullptr)
1038 {
1039 return setBinding(Qt::makePropertyBinding(std::forward<Functor>(f), location));
1040 }
1041#else
1042 template <typename Functor>
1043 QPropertyBinding<T> setBinding(Functor f);
1044#endif
1045
1046 bool hasBinding() const
1047 {
1048 return QBindable<T>(aliasedProperty(), iface).hasBinding();
1049 }
1050
1051 QPropertyBinding<T> binding() const
1052 {
1053 return QBindable<T>(aliasedProperty(), iface).binding();
1054 }
1055
1056 QPropertyBinding<T> takeBinding()
1057 {
1058 return QBindable<T>(aliasedProperty(), iface).takeBinding();
1059 }
1060
1061 template<typename Functor>
1062 QPropertyChangeHandler<Functor> onValueChanged(Functor f)
1063 {
1064 return QBindable<T>(aliasedProperty(), iface).onValueChanged(std::move(f));
1065 }
1066
1067 template<typename Functor>
1068 QPropertyChangeHandler<Functor> subscribe(Functor f)
1069 {
1070 return QBindable<T>(aliasedProperty(), iface).subscribe(std::move(f));
1071 }
1072
1073 template<typename Functor>
1074 QPropertyNotifier addNotifier(Functor f)
1075 {
1076 return QBindable<T>(aliasedProperty(), iface).addNotifier(std::move(f));
1077 }
1078
1079 bool isValid() const
1080 {
1081 return aliasedProperty() != nullptr;
1082 }
1083 QT_WARNING_POP
1084};
1085#endif // QT_DEPRECATED_SINCE(6, 6)
1086
1087template<typename Class, typename T, auto Offset, auto Signal = nullptr>
1089{
1091 static bool constexpr HasSignal = !std::is_same_v<decltype(Signal), std::nullptr_t>;
1092 using SignalTakesValue = std::is_invocable<decltype(Signal), Class, T>;
1093 Class *owner()
1094 {
1095 char *that = reinterpret_cast<char *>(this);
1096 return reinterpret_cast<Class *>(that - QtPrivate::detail::getOffset(Offset));
1097 }
1098 const Class *owner() const
1099 {
1100 char *that = const_cast<char *>(reinterpret_cast<const char *>(this));
1101 return reinterpret_cast<Class *>(that - QtPrivate::detail::getOffset(Offset));
1102 }
1103 static void signalCallBack(QUntypedPropertyData *o)
1104 {
1105 QObjectBindableProperty *that = static_cast<QObjectBindableProperty *>(o);
1106 if constexpr (HasSignal) {
1107 if constexpr (SignalTakesValue::value)
1108 (that->owner()->*Signal)(that->valueBypassingBindings());
1109 else
1110 (that->owner()->*Signal)();
1111 }
1112 }
1113public:
1118
1120 explicit QObjectBindableProperty(const T &initialValue) : QPropertyData<T>(initialValue) {}
1121 explicit QObjectBindableProperty(T &&initialValue) : QPropertyData<T>(std::move(initialValue)) {}
1122 explicit QObjectBindableProperty(const QPropertyBinding<T> &binding)
1124 { setBinding(binding); }
1125#ifndef Q_QDOC
1126 template <typename Functor>
1127 explicit QObjectBindableProperty(Functor &&f, const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION,
1128 typename std::enable_if_t<std::is_invocable_r_v<T, Functor&>> * = nullptr)
1129 : QObjectBindableProperty(QPropertyBinding<T>(std::forward<Functor>(f), location))
1130 {}
1131#else
1132 template <typename Functor>
1133 explicit QObjectBindableProperty(Functor &&f);
1134#endif
1135
1136 QT_DECLARE_EQUALITY_OPERATORS_HELPER(QObjectBindableProperty, QObjectBindableProperty, /* non-constexpr */, noexcept(false), template <typename Ty = T, std::enable_if_t<QTypeTraits::has_operator_equal_v<Ty>>* = nullptr>)
1137 QT_DECLARE_EQUALITY_OPERATORS_HELPER(QObjectBindableProperty, T, /* non-constexpr */, noexcept(false), template <typename Ty = T, std::enable_if_t<QTypeTraits::has_operator_equal_v<Ty>>* = nullptr>)
1138 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(QObjectBindableProperty, T, /* non-constexpr */, noexcept(false), template <typename Ty = T, std::enable_if_t<QTypeTraits::has_operator_equal_v<Ty>>* = nullptr>)
1139
1141 {
1143 return this->val;
1144 }
1145
1147 {
1148 if constexpr (QTypeTraits::is_dereferenceable_v<T>) {
1149 return value();
1150 } else if constexpr (std::is_pointer_v<T>) {
1151 value();
1152 return this->val;
1153 } else {
1154 return;
1155 }
1156 }
1157
1159 {
1160 return value();
1161 }
1162
1164 {
1165 return value();
1166 }
1167
1169 {
1170 auto *bd = qGetBindingStorage(owner())->bindingData(this);
1171 if (bd)
1172 bd->removeBinding();
1173 if (this->val == t)
1174 return;
1175 this->val = t;
1176 notify(bd);
1177 }
1178
1179 void notify() {
1180 auto *bd = qGetBindingStorage(owner())->bindingData(this);
1181 notify(bd);
1182 }
1183
1185 {
1186 auto *bd = qGetBindingStorage(owner())->bindingData(this);
1187 if (bd)
1188 bd->removeBinding();
1189 if (this->val == t)
1190 return;
1191 this->val = std::move(t);
1192 notify(bd);
1193 }
1194
1196 {
1198 return *this;
1199 }
1200
1202 {
1204 return *this;
1205 }
1206
1213
1215 {
1217 return false;
1218 setBinding(static_cast<const QPropertyBinding<T> &>(newBinding));
1219 return true;
1220 }
1221
1222#ifndef Q_QDOC
1223 template <typename Functor>
1230#else
1231 template <typename Functor>
1233#endif
1234
1235 bool hasBinding() const
1236 {
1237 auto *bd = qGetBindingStorage(owner())->bindingData(this);
1238 return bd && bd->binding() != nullptr;
1239 }
1240
1242 {
1243 auto *bd = qGetBindingStorage(owner())->bindingData(this);
1244 return static_cast<QPropertyBinding<T> &&>(QUntypedPropertyBinding(bd ? bd->binding() : nullptr));
1245 }
1246
1248 {
1249 return setBinding(QPropertyBinding<T>());
1250 }
1251
1252 template<typename Functor>
1254 {
1255 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
1256 return QPropertyChangeHandler<Functor>(*this, std::move(f));
1257 }
1258
1259 template<typename Functor>
1261 {
1262 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
1263 f();
1264 return onValueChanged(std::move(f));
1265 }
1266
1267 template<typename Functor>
1269 {
1270 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
1271 return QPropertyNotifier(*this, std::move(f));
1272 }
1273
1275 {
1276 auto *storage = const_cast<QBindingStorage *>(qGetBindingStorage(owner()));
1277 return *storage->bindingData(const_cast<ThisType *>(this), true);
1278 }
1279private:
1280 template <typename Ty = T, std::enable_if_t<QTypeTraits::has_operator_equal_v<Ty>>* = nullptr>
1282 {
1283 return lhs.value() == rhs.value();
1284 }
1285
1286 template <typename Ty = T, std::enable_if_t<QTypeTraits::has_operator_equal_v<Ty>>* = nullptr>
1287 friend bool comparesEqual(const QObjectBindableProperty &lhs, const T &rhs)
1288 {
1289 return lhs.value() == rhs;
1290 }
1291
1293 {
1294 if (binding)
1296 if constexpr (HasSignal) {
1297 if constexpr (SignalTakesValue::value)
1298 (owner()->*Signal)(this->valueBypassingBindings());
1299 else
1300 (owner()->*Signal)();
1301 }
1302 }
1303};
1304
1305#define QT_OBJECT_BINDABLE_PROPERTY_3(Class, Type, name)
1306 static constexpr size_t _qt_property_##name##_offset() {
1307 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1308 return offsetof(Class, name);
1309 QT_WARNING_POP
1310 }
1311 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, nullptr> name;
1312
1313#define QT_OBJECT_BINDABLE_PROPERTY_4(Class, Type, name, Signal)
1314 static constexpr size_t _qt_property_##name##_offset() {
1315 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1316 return offsetof(Class, name);
1317 QT_WARNING_POP
1318 }
1319 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, Signal> name;
1320
1321#define Q_OBJECT_BINDABLE_PROPERTY(...)
1322 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1323 QT_OVERLOADED_MACRO(QT_OBJECT_BINDABLE_PROPERTY, __VA_ARGS__)
1324 QT_WARNING_POP
1325
1326#define QT_OBJECT_BINDABLE_PROPERTY_WITH_ARGS_4(Class, Type, name, value)
1327 static constexpr size_t _qt_property_##name##_offset()
1328 {
1329 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1330 return offsetof(Class, name);
1331 QT_WARNING_POP
1332 }
1333 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, nullptr> name =
1334 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, nullptr>(
1335 value);
1336
1337#define QT_OBJECT_BINDABLE_PROPERTY_WITH_ARGS_5(Class, Type, name, value, Signal)
1338 static constexpr size_t _qt_property_##name##_offset()
1339 {
1340 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1341 return offsetof(Class, name);
1342 QT_WARNING_POP
1343 }
1344 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, Signal> name =
1345 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, Signal>(
1346 value);
1347
1348#define Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(...)
1349 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1350 QT_OVERLOADED_MACRO(QT_OBJECT_BINDABLE_PROPERTY_WITH_ARGS, __VA_ARGS__)
1351 QT_WARNING_POP
1352
1353template<typename Class, typename T, auto Offset, auto Getter>
1355{
1356 Class *owner()
1357 {
1358 char *that = reinterpret_cast<char *>(this);
1359 return reinterpret_cast<Class *>(that - QtPrivate::detail::getOffset(Offset));
1360 }
1361 const Class *owner() const
1362 {
1363 char *that = const_cast<char *>(reinterpret_cast<const char *>(this));
1364 return reinterpret_cast<Class *>(that - QtPrivate::detail::getOffset(Offset));
1365 }
1366
1367public:
1368 using value_type = T;
1370
1372
1374 {
1375 qGetBindingStorage(owner())->registerDependency(this);
1376 return (owner()->*Getter)();
1377 }
1378
1380 operator->() const
1381 {
1382 if constexpr (QTypeTraits::is_dereferenceable_v<T>)
1383 return value();
1384 else
1385 return;
1386 }
1387
1389 {
1390 return value();
1391 }
1392
1394 {
1395 return value();
1396 }
1397
1398 constexpr bool hasBinding() const { return false; }
1399
1400 template<typename Functor>
1402 {
1403 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
1404 return QPropertyChangeHandler<Functor>(*this, std::move(f));
1405 }
1406
1407 template<typename Functor>
1409 {
1410 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
1411 f();
1412 return onValueChanged(std::move(f));
1413 }
1414
1415 template<typename Functor>
1417 {
1418 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
1419 return QPropertyNotifier(*this, std::move(f));
1420 }
1421
1423 {
1424 auto *storage = const_cast<QBindingStorage *>(qGetBindingStorage(owner()));
1425 return *storage->bindingData(const_cast<QObjectComputedProperty *>(this), true);
1426 }
1427
1428 void notify() {
1429 // computed property can't store a binding, so there's nothing to mark
1430 auto *storage = const_cast<QBindingStorage *>(qGetBindingStorage(owner()));
1431 auto bd = storage->bindingData(const_cast<QObjectComputedProperty *>(this), false);
1432 if (bd)
1434 }
1435};
1436
1437#define Q_OBJECT_COMPUTED_PROPERTY(Class, Type, name, ...)
1438 static constexpr size_t _qt_property_##name##_offset() {
1439 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1440 return offsetof(Class, name);
1441 QT_WARNING_POP
1442 }
1443 QObjectComputedProperty<Class, Type, Class::_qt_property_##name##_offset, __VA_ARGS__> name;
1444
1445#undef QT_SOURCE_LOCATION_NAMESPACE
1446
1447QT_END_NAMESPACE
1448
1449#endif // QPROPERTY_H
QPropertyBinding< T > makeBinding(const QPropertyBindingSourceLocation &location=QT_PROPERTY_DEFAULT_BINDING_LOCATION) const
Constructs a binding evaluating to the underlying property's value, using a specified source location...
Definition qproperty.h:899
QPropertyBinding< T > binding() const
Returns the currently set binding of the underlying property.
Definition qproperty.h:903
T value() const
Returns the underlying property's current value.
Definition qproperty.h:941
void setValue(const T &value)
Sets the underlying property's value to value.
Definition qproperty.h:951
friend class QPropertyAlias
Definition qproperty.h:879
QBindable(QObject *obj, const QMetaProperty &property)
Definition qproperty.h:893
QPropertyBinding< T > setBinding(Functor &&f, const QPropertyBindingSourceLocation &location=QT_PROPERTY_DEFAULT_BINDING_LOCATION, std::enable_if_t< std::is_invocable_v< Functor > > *=nullptr)
Definition qproperty.h:930
QBindable(const QUntypedBindable &b)
Definition qproperty.h:885
QPropertyBinding< T > setBinding(const QPropertyBinding< T > &binding)
Sets the underlying property's binding to binding.
Definition qproperty.h:914
QBindable(QObject *obj, const char *property)
Definition qproperty.h:896
QPropertyBinding< T > takeBinding()
Removes the currently set binding of the underlying property and returns it.
Definition qproperty.h:908
\inmodule QtCore
\inmodule QtCore
Definition qproperty.h:1089
QObjectBindableProperty(const T &initialValue)
Constructs a property with the provided initialValue.
Definition qproperty.h:1120
QObjectBindableProperty()=default
typename QPropertyData< T >::rvalue_ref rvalue_ref
Definition qproperty.h:1116
typename QPropertyData< T >::value_type value_type
Definition qproperty.h:1114
QObjectBindableProperty(T &&initialValue)
Move-Constructs a property with the provided initialValue.
Definition qproperty.h:1121
typename QPropertyData< T >::arrow_operator_result arrow_operator_result
Definition qproperty.h:1117
QObjectBindableProperty(Functor &&f, const QPropertyBindingSourceLocation &location=QT_PROPERTY_DEFAULT_BINDING_LOCATION, typename std::enable_if_t< std::is_invocable_r_v< T, Functor & > > *=nullptr)
Definition qproperty.h:1127
QObjectBindableProperty(const QPropertyBinding< T > &binding)
Definition qproperty.h:1122
typename QPropertyData< T >::parameter_type parameter_type
Definition qproperty.h:1115
\macro Q_OBJECT_BINDABLE_PROPERTY(containingClass, type, name, signal)
QPropertyBinding< T > binding() const
operator parameter_type() const
typename QPropertyData< T >::value_type value_type
QtPrivate::QPropertyBindingData & bindingData() const
QObjectCompatProperty & operator=(parameter_type newValue)
typename QPropertyData< T >::arrow_operator_result arrow_operator_result
typename QPropertyData< T >::parameter_type parameter_type
parameter_type value() const
QPropertyChangeHandler< Functor > onValueChanged(Functor f)
void setValue(parameter_type t)
void removeBindingUnlessInWrapper()
bool setBinding(const QUntypedPropertyBinding &newBinding)
QPropertyBinding< T > setBinding(Functor &&f, const QPropertyBindingSourceLocation &location=QT_PROPERTY_DEFAULT_BINDING_LOCATION, std::enable_if_t< std::is_invocable_v< Functor > > *=nullptr)
arrow_operator_result operator->() const
QObjectCompatProperty(T &&initialValue)
QPropertyNotifier addNotifier(Functor f)
parameter_type operator*() const
QObjectCompatProperty(const T &initialValue)
QPropertyBinding< T > takeBinding()
QPropertyChangeHandler< Functor > subscribe(Functor f)
bool hasBinding() const
QPropertyBinding< T > setBinding(const QPropertyBinding< T > &newBinding)
\macro Q_OBJECT_COMPAT_PROPERTY(containingClass, type, name, callback)
Definition qproperty.h:1355
QObjectComputedProperty()=default
parameter_type value() const
Definition qproperty.h:1373
\inmodule QtCore
Definition qproperty.h:133
QPropertyBinding(const QUntypedPropertyBinding &binding)
Definition qproperty.h:207
QPropertyBinding()=default
QPropertyBinding(Functor &&f, const QPropertyBindingSourceLocation &location)
Definition qproperty.h:201
\inmodule QtCore
Definition qproperty.h:294
\inmodule QtCore
Definition qproperty.h:71
static constexpr bool UseReferences
Definition qproperty.h:77
void setValueBypassingBindings(parameter_type v)
Sets the data value stored in this property to v.
Definition qproperty.h:91
QPropertyData()=default
QPropertyData(parameter_type t)
Definition qproperty.h:86
~QPropertyData()=default
parameter_type valueBypassingBindings() const
Returns the data stored in this property.
Definition qproperty.h:90
\inmodule QtCore
Definition qproperty.h:321
QUntypedPropertyData * aliasData
Definition qproperty.h:256
void(*)(QPropertyObserver *, QUntypedPropertyData *) ChangeHandler
Definition qproperty.h:238
ChangeHandler changeHandler
Definition qproperty.h:255
QPropertyBindingPrivate * binding
Definition qproperty.h:254
\inmodule QtCore
Definition qproperty.h:353
typename QPropertyData< T >::arrow_operator_result arrow_operator_result
Definition qproperty.h:379
QProperty(rvalue_ref initialValue)
Definition qproperty.h:383
void setValue(rvalue_ref newValue)
Definition qproperty.h:448
typename QPropertyData< T >::value_type value_type
Definition qproperty.h:376
QPropertyChangeHandler< Functor > subscribe(Functor f)
Definition qproperty.h:524
QPropertyBinding< T > takeBinding()
Disassociates the binding expression from this property and returns it.
Definition qproperty.h:511
bool hasBinding() const
Definition qproperty.h:504
bool setBinding(const QUntypedPropertyBinding &newBinding)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qproperty.h:483
friend void operator!=(const QProperty &, const QProperty< U > &) QPROPERTY_DECL_DELETED_EQ_OP
QPropertyNotifier addNotifier(Functor f)
Definition qproperty.h:532
typename QPropertyData< T >::rvalue_ref rvalue_ref
Definition qproperty.h:378
QPropertyChangeHandler< Functor > onValueChanged(Functor f)
Registers the given functor f as a callback that shall be called whenever the value of the property c...
Definition qproperty.h:517
QPropertyBinding< T > setBinding(Functor &&f, const QPropertyBindingSourceLocation &location=QT_PROPERTY_DEFAULT_BINDING_LOCATION, std::enable_if_t< std::is_invocable_v< Functor > > *=nullptr)
Definition qproperty.h:493
void setValue(parameter_type newValue)
Assigns newValue to this property and removes the property's associated binding, if present.
Definition qproperty.h:457
QProperty()=default
Constructs a property with a default constructed instance of T.
QProperty(const QPropertyBinding< T > &binding)
Constructs a property that is tied to the provided binding expression.
Definition qproperty.h:384
parameter_type value() const
Returns the value of the property.
Definition qproperty.h:420
QPropertyBinding< T > setBinding(const QPropertyBinding< T > &newBinding)
Associates the value of this property with the provided newBinding expression and returns the previou...
Definition qproperty.h:478
QProperty(Functor &&f, const QPropertyBindingSourceLocation &location=QT_PROPERTY_DEFAULT_BINDING_LOCATION, typename std::enable_if_t< std::is_invocable_r_v< T, Functor & > > *=nullptr)
Definition qproperty.h:389
const QtPrivate::QPropertyBindingData & bindingData() const
Definition qproperty.h:538
typename QPropertyData< T >::parameter_type parameter_type
Definition qproperty.h:377
QProperty< T > & operator=(rvalue_ref newValue)
Definition qproperty.h:466
arrow_operator_result operator->() const
Definition qproperty.h:426
QProperty< T > & operator=(parameter_type newValue)
Assigns newValue to this property and returns a reference to this QProperty.
Definition qproperty.h:472
QPropertyBinding< T > binding() const
Returns the binding expression that is associated with this property.
Definition qproperty.h:506
parameter_type operator*() const
Definition qproperty.h:438
operator parameter_type() const
Definition qproperty.h:443
~QProperty()=default
Destroys the property.
QProperty(parameter_type initialValue)
Definition qproperty.h:382
RAII class around Qt::beginPropertyUpdateGroup()/QtendPropertyUpdateGroup().
Definition qproperty.h:59
~QTimerPrivate() override
QTimerPrivate(QTimer *qq)
Definition qtimer_p.h:28
void setIntervalDuration(std::chrono::nanoseconds nsec)
Definition qtimer_p.h:43
static constexpr int INV_TIMER
Definition qtimer_p.h:41
void setInterval(int msec)
Definition qtimer_p.h:53
bool isActive() const
Definition qtimer_p.h:59
const bool isQTimer
Definition qtimer_p.h:71
QTimerPrivate(std::chrono::nanoseconds nsec, QChronoTimer *qq)
Definition qtimer_p.h:33
Qt::TimerId id
Definition qtimer_p.h:61
\inmodule QtCore
Definition qtimer.h:21
\inmodule QtCore
Definition qproperty.h:743
QUntypedPropertyBinding binding() const
Returns the underlying property's binding if there is any, or a default constructed QUntypedPropertyB...
Definition qproperty.h:823
QUntypedPropertyBinding makeBinding(const QPropertyBindingSourceLocation &location=QT_PROPERTY_DEFAULT_BINDING_LOCATION) const
Creates a binding returning the underlying properties' value, using a specified source location.
Definition qproperty.h:767
bool hasBinding() const
Returns true if the underlying property has a binding.
Definition qproperty.h:853
constexpr QUntypedBindable()=default
Default-constructs a QUntypedBindable.
QMetaType metaType() const
Definition qproperty.h:858
const QtPrivate::QBindableInterface * iface
Definition qproperty.h:747
QPropertyChangeHandler< Functor > onValueChanged(Functor f) const
Installs f as a change handler.
Definition qproperty.h:801
QUntypedPropertyBinding takeBinding()
Removes the currently set binding from the property and returns it.
Definition qproperty.h:772
QPropertyNotifier addNotifier(Functor f)
Installs f as a change handler.
Definition qproperty.h:816
QUntypedPropertyData * data
Definition qproperty.h:746
bool isBindable() const
Definition qproperty.h:764
bool isValid() const
Returns true if the QUntypedBindable is valid.
Definition qproperty.h:763
bool setBinding(const QUntypedPropertyBinding &binding)
Sets the underlying property's binding to binding.
Definition qproperty.h:834
bool isReadOnly() const
Definition qproperty.h:765
QUntypedBindable(Property *p)
Constructs a QUntypedBindable from the property property.
Definition qproperty.h:758
QPropertyChangeHandler< Functor > subscribe(Functor f) const
Behaves like a call to f followed by onValueChanged(f),.
Definition qproperty.h:809
constexpr QUntypedBindable(QUntypedPropertyData *d, const QtPrivate::QBindableInterface *i)
Definition qproperty.h:748
void observe(QPropertyObserver *observer) const
Definition qproperty.h:789
\inmodule QtCore
Definition qproperty.h:160
static constexpr QBindableInterface iface
Definition qproperty.h:607
QPropertyBindingData & bindingData()
friend class QT_PREPEND_NAMESPACE(QUntypedBindable)
const QMetaProperty & metaProperty() const
static QPropertyAdaptorSlotObject * cast(QSlotObjectBase *ptr, int propertyIndex)
const QPropertyBindingData & bindingData() const
Combined button and popup list for selecting options.
void printMetaTypeMismatch(QMetaType actual, QMetaType expected)
void printUnsuitableBindableWarning(QAnyStringView prefix, BindableWarnings::Reason reason)
Q_CORE_EXPORT void printSignalArgumentsWithCustomGetter()
void setter(QUntypedPropertyData *d, const void *value)
void getter(const QUntypedPropertyData *d, void *value)
bool bindingWrapper(QMetaType type, QUntypedPropertyData *d, QtPrivate::QPropertyBindingFunction binding, QUntypedPropertyData *temp, void *value)
QUntypedPropertyBinding setBinding(QUntypedPropertyData *d, const QUntypedPropertyBinding &binding)
Definition qproperty.h:699
constexpr QBindableInterface iface
Definition qproperty.h:718
bool bindingWrapper(QMetaType type, QUntypedPropertyData *d, QtPrivate::QPropertyBindingFunction binding)
Definition qproperty.h:688
QUntypedPropertyBinding makeBinding(const QUntypedPropertyData *d, const QPropertyBindingSourceLocation &location)
Definition qproperty.h:705
void setObserver(const QUntypedPropertyData *d, QPropertyObserver *observer)
void assertObjectType(QObjectPrivate *d)
Definition qobject_p.h:251
Q_CORE_EXPORT bool isAnyBindingEvaluating()
Q_CORE_EXPORT void restoreBindingStatus(BindingEvaluationState *status)
const QObject * getQObject(const QObjectPrivate *d)
Definition qobject_p.h:246
Q_CORE_EXPORT bool isPropertyInBindingWrapper(const QUntypedPropertyData *property)
Definition qcompare.h:111
auto makePropertyBinding(Functor &&f, const QPropertyBindingSourceLocation &location=QT_PROPERTY_DEFAULT_BINDING_LOCATION, std::enable_if_t< std::is_invocable_v< Functor > > *=nullptr)
Definition qproperty.h:214
Q_CORE_EXPORT void beginPropertyUpdateGroup()
QPropertyBinding< PropertyType > makePropertyBinding(const QProperty< PropertyType > &otherProperty, const QPropertyBindingSourceLocation &location=QT_PROPERTY_DEFAULT_BINDING_LOCATION)
Definition qproperty.h:568
Q_CORE_EXPORT void endPropertyUpdateGroup()
#define __has_include(x)
#define QT_CONCAT(B, M, m, u)
Definition qobject_p.h:43
QBindingStorage * qGetBindingStorage(QObjectPrivate *o)
Definition qobject_p.h:454
QBindingStorage * qGetBindingStorage(QObjectPrivate::ExtraData *ed)
Definition qobject_p.h:462
const QBindingStorage * qGetBindingStorage(const QObjectPrivate *o)
Definition qobject_p.h:450
#define QPROPERTY_DECL_DELETED_EQ_OP
Definition qproperty.h:411
#define Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(...)
Definition qproperty.h:1348
#define QT_PROPERTY_DEFAULT_BINDING_LOCATION
Definition qproperty.h:48
#define Q_OBJECT_COMPUTED_PROPERTY(Class, Type, name, ...)
Definition qproperty.h:1437
#define Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(...)
QBindingObserverPtr()=default
QPropertyObserver * operator->()
QPropertyBindingPrivate * binding() const noexcept
static QPropertyProxyBindingData * proxyData(QtPrivate::QPropertyBindingData *ptr)
static void fixupAfterMove(QtPrivate::QPropertyBindingData *ptr)
Q_ALWAYS_INLINE void addObserver(QPropertyObserver *observer)
Definition qproperty.cpp:41
const QtPrivate::QPropertyBindingData * ptr
Definition qproperty_p.h:75
static QPropertyBindingDataPointer get(QProperty< T > &property)
Definition qproperty_p.h:97
QPropertyBindingPrivate * binding() const
Definition qproperty_p.h:77
void setObservers(QPropertyObserver *observer)
Definition qproperty_p.h:82
QPropertyObserverPointer firstObserver() const
void setFirstObserver(QPropertyObserver *observer)
QPropertyObserver * next() const
void noSelfDependencies(QPropertyBindingPrivate *binding)
void notify(QUntypedPropertyData *propertyDataPtr)
QPropertyBindingPrivate * binding() const
void evaluateBindings(PendingBindingObserverList &bindingObservers, QBindingStatus *status)
void observeProperty(QPropertyBindingDataPointer property)
QPropertyObserver * ptr
QPropertyObserverPointer nextObserver() const
void setBindingToNotify_unsafe(QPropertyBindingPrivate *binding)
void setChangeHandler(QPropertyObserver::ChangeHandler changeHandler)
void setBindingToNotify(QPropertyBindingPrivate *binding)
void(* BeginCallback)(QObject *caller, int signal_or_method_index, void **argv)
Definition qobject_p.h:64
BeginCallback slot_begin_callback
Definition qobject_p.h:67
EndCallback slot_end_callback
Definition qobject_p.h:69
EndCallback signal_end_callback
Definition qobject_p.h:68
BeginCallback signal_begin_callback
Definition qobject_p.h:66
void(* EndCallback)(QObject *caller, int signal_or_method_index)
Definition qobject_p.h:65
static QtPrivate::QBindableInterface const * getInterface(const QUntypedBindable &bindable)
static QUntypedPropertyData * getPropertyData(const QUntypedBindable &bindable)
QPropertyBindingPrivate * binding
QVarLengthArray< const QPropertyBindingData *, 8 > alreadyCaptureProperties
BindingEvaluationState(QPropertyBindingPrivate *binding, QBindingStatus *status)
BindingEvaluationState * previousState
BindingEvaluationState ** currentState
QtPrivate::BindingEvaluationState ** currentlyEvaluatingBindingList
CompatPropertySafePoint * previousState
CompatPropertySafePoint ** currentState
QUntypedPropertyData * property
QtPrivate::BindingEvaluationState * bindingState
void(*)(const QUntypedPropertyData *d, void *value) Getter
Definition qproperty.h:582
void(*)(const QUntypedPropertyData *d, QPropertyObserver *observer) SetObserver
Definition qproperty.h:587
void(*)(QUntypedPropertyData *d, const void *value) Setter
Definition qproperty.h:583
static constexpr quintptr MetaTypeAccessorFlag
Definition qproperty.h:597