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 &getter,
720 &setter,
721 &getBinding,
722 &setBinding<T>,
723 &makeBinding<T>,
726};
727}
728}
729
731{
732 friend struct QUntypedBindablePrivate; // allows access to internal data
733protected:
736 constexpr QUntypedBindable(QUntypedPropertyData *d, const QtPrivate::QBindableInterface *i)
737 : data(d), iface(i)
738 {}
739
742
743public:
744 constexpr QUntypedBindable() = default;
745 template<typename Property>
746 QUntypedBindable(Property *p)
747 : data(const_cast<std::remove_cv_t<Property> *>(p)),
749 { Q_ASSERT(data && iface); }
750
751 bool isValid() const { return data != nullptr; }
752 bool isBindable() const { return iface && iface->getBinding; }
753 bool isReadOnly() const { return !(iface && iface->setBinding && iface->setObserver); }
754
755 QUntypedPropertyBinding makeBinding(const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION) const
756 {
757 return iface ? iface->makeBinding(data, location) : QUntypedPropertyBinding();
758 }
759
761 {
762 if (!iface)
763 return QUntypedPropertyBinding {};
764 // We do not have a dedicated takeBinding function pointer in the interface
765 // therefore we synthesize takeBinding by retrieving the binding with binding
766 // and calling setBinding with a default constructed QUntypedPropertyBinding
767 // afterwards.
768 if (!(iface->getBinding && iface->setBinding))
769 return QUntypedPropertyBinding {};
770 return [&] {
771 QUntypedPropertyBinding binding = iface->getBinding(data);
772 iface->setBinding(data, QUntypedPropertyBinding{});
773 return binding;
774 }();
775 }
776
777 void observe(QPropertyObserver *observer) const
778 {
779 if (iface)
780 iface->setObserver(data, observer);
781#ifndef QT_NO_DEBUG
782 else
785#endif
786 }
787
788 template<typename Functor>
789 QPropertyChangeHandler<Functor> onValueChanged(Functor f) const
790 {
791 QPropertyChangeHandler<Functor> handler(std::move(f));
792 observe(&handler);
793 return handler;
794 }
795
796 template<typename Functor>
797 QPropertyChangeHandler<Functor> subscribe(Functor f) const
798 {
799 f();
800 return onValueChanged(std::move(f));
801 }
802
803 template<typename Functor>
805 {
806 QPropertyNotifier handler(std::move(f));
807 observe(&handler);
808 return handler;
809 }
810
812 {
813 if (!isBindable()) {
814#ifndef QT_NO_DEBUG
817#endif
818 return QUntypedPropertyBinding();
819 }
820 return iface->getBinding(data);
821 }
822 bool setBinding(const QUntypedPropertyBinding &binding)
823 {
824 if (isReadOnly()) {
825#ifndef QT_NO_DEBUG
828 QtPrivate::BindableWarnings::printUnsuitableBindableWarning("setBinding: Could not set binding via bindable interface.", errorType);
829#endif
830 return false;
831 }
832 if (!binding.isNull() && binding.valueMetaType() != metaType()) {
833#ifndef QT_NO_DEBUG
834 QtPrivate::BindableWarnings::printMetaTypeMismatch(metaType(), binding.valueMetaType());
835#endif
836 return false;
837 }
838 iface->setBinding(data, binding);
839 return true;
840 }
841 bool hasBinding() const
842 {
843 return !binding().isNull();
844 }
845
847 {
848 if (!(iface && data))
849 return QMetaType();
850 if (iface->metaType)
851 return iface->metaType();
852 // ### Qt 7: Change the metatype function to take data as its argument
853 // special casing for QML's proxy bindable: allow multiplexing in the getter
854 // function to retrieve the metatype from data
855 Q_ASSERT(iface->getter);
856 QMetaType result;
857 iface->getter(data, reinterpret_cast<void *>(quintptr(&result) | QtPrivate::QBindableInterface::MetaTypeAccessorFlag));
858 return result;
859 }
860
861};
862
863template<typename T>
864class QBindable : public QUntypedBindable
865{
866 template<typename U>
867 friend class QPropertyAlias;
868 constexpr QBindable(QUntypedPropertyData *d, const QtPrivate::QBindableInterface *i)
869 : QUntypedBindable(d, i)
870 {}
871public:
872 using QUntypedBindable::QUntypedBindable;
874 {
875 if (iface && metaType() != QMetaType::fromType<T>()) {
876 data = nullptr;
877 iface = nullptr;
878 }
879 }
880
881 explicit QBindable(QObject *obj, const QMetaProperty &property)
882 : QUntypedBindable(obj, property, &QtPrivate::PropertyAdaptorSlotObjectHelpers::iface<T>) {}
883
884 explicit QBindable(QObject *obj, const char *property)
885 : QUntypedBindable(obj, property, &QtPrivate::PropertyAdaptorSlotObjectHelpers::iface<T>) {}
886
887 QPropertyBinding<T> makeBinding(const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION) const
888 {
889 return static_cast<QPropertyBinding<T> &&>(QUntypedBindable::makeBinding(location));
890 }
892 {
893 return static_cast<QPropertyBinding<T> &&>(QUntypedBindable::binding());
894 }
895
897 {
898 return static_cast<QPropertyBinding<T> &&>(QUntypedBindable::takeBinding());
899 }
900
901 using QUntypedBindable::setBinding;
903 {
904 Q_ASSERT(!iface || binding.isNull() || binding.valueMetaType() == metaType());
905
906 if (iface && iface->setBinding)
907 return static_cast<QPropertyBinding<T> &&>(iface->setBinding(data, binding));
908#ifndef QT_NO_DEBUG
909 if (!iface)
911 else
913#endif
914 return QPropertyBinding<T>();
915 }
916#ifndef Q_QDOC
917 template <typename Functor>
919 const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION,
920 std::enable_if_t<std::is_invocable_v<Functor>> * = nullptr)
921 {
922 return setBinding(Qt::makePropertyBinding(std::forward<Functor>(f), location));
923 }
924#else
925 template <typename Functor>
926 QPropertyBinding<T> setBinding(Functor f);
927#endif
928
929 T value() const
930 {
931 if (iface) {
932 T result;
933 iface->getter(data, &result);
934 return result;
935 }
936 return T{};
937 }
938
939 void setValue(const T &value)
940 {
941 if (iface && iface->setter)
942 iface->setter(data, &value);
943 }
944};
945
946#if QT_DEPRECATED_SINCE(6, 6)
947template<typename T>
948class QT_DEPRECATED_VERSION_X_6_6("Class was only meant for internal use, use a QProperty and add a binding to the target")
949QPropertyAlias : public QPropertyObserver
950{
951 Q_DISABLE_COPY_MOVE(QPropertyAlias)
952 const QtPrivate::QBindableInterface *iface = nullptr;
953
954public:
955 QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
956 QPropertyAlias(QProperty<T> *property)
957 : QPropertyObserver(property),
958 iface(&QtPrivate::QBindableInterfaceForProperty<QProperty<T>>::iface)
959 {
960 if (iface)
961 iface->setObserver(aliasedProperty(), this);
962 }
963
964 template <typename Property, QtPrivate::IsUntypedPropertyData<Property> = true>
965 QPropertyAlias(Property *property)
966 : QPropertyObserver(property),
967 iface(&QtPrivate::QBindableInterfaceForProperty<Property>::iface)
968 {
969 if (iface)
970 iface->setObserver(aliasedProperty(), this);
971 }
972
973 QPropertyAlias(QPropertyAlias<T> *alias)
974 : QPropertyObserver(alias->aliasedProperty()),
975 iface(alias->iface)
976 {
977 if (iface)
978 iface->setObserver(aliasedProperty(), this);
979 }
980
981 QPropertyAlias(const QBindable<T> &property)
982 : QPropertyObserver(property.data),
983 iface(property.iface)
984 {
985 if (iface)
986 iface->setObserver(aliasedProperty(), this);
987 }
988
989 T value() const
990 {
991 T t = T();
992 if (auto *p = aliasedProperty())
993 iface->getter(p, &t);
994 return t;
995 }
996
997 operator T() const { return value(); }
998
999 void setValue(const T &newValue)
1000 {
1001 if (auto *p = aliasedProperty())
1002 iface->setter(p, &newValue);
1003 }
1004
1005 QPropertyAlias<T> &operator=(const T &newValue)
1006 {
1007 setValue(newValue);
1008 return *this;
1009 }
1010
1011 QPropertyBinding<T> setBinding(const QPropertyBinding<T> &newBinding)
1012 {
1013 return QBindable<T>(aliasedProperty(), iface).setBinding(newBinding);
1014 }
1015
1016 bool setBinding(const QUntypedPropertyBinding &newBinding)
1017 {
1018 return QBindable<T>(aliasedProperty(), iface).setBinding(newBinding);
1019 }
1020
1021#ifndef Q_QDOC
1022 template <typename Functor>
1023 QPropertyBinding<T> setBinding(Functor &&f,
1024 const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION,
1025 std::enable_if_t<std::is_invocable_v<Functor>> * = nullptr)
1026 {
1027 return setBinding(Qt::makePropertyBinding(std::forward<Functor>(f), location));
1028 }
1029#else
1030 template <typename Functor>
1031 QPropertyBinding<T> setBinding(Functor f);
1032#endif
1033
1034 bool hasBinding() const
1035 {
1036 return QBindable<T>(aliasedProperty(), iface).hasBinding();
1037 }
1038
1039 QPropertyBinding<T> binding() const
1040 {
1041 return QBindable<T>(aliasedProperty(), iface).binding();
1042 }
1043
1044 QPropertyBinding<T> takeBinding()
1045 {
1046 return QBindable<T>(aliasedProperty(), iface).takeBinding();
1047 }
1048
1049 template<typename Functor>
1050 QPropertyChangeHandler<Functor> onValueChanged(Functor f)
1051 {
1052 return QBindable<T>(aliasedProperty(), iface).onValueChanged(std::move(f));
1053 }
1054
1055 template<typename Functor>
1056 QPropertyChangeHandler<Functor> subscribe(Functor f)
1057 {
1058 return QBindable<T>(aliasedProperty(), iface).subscribe(std::move(f));
1059 }
1060
1061 template<typename Functor>
1062 QPropertyNotifier addNotifier(Functor f)
1063 {
1064 return QBindable<T>(aliasedProperty(), iface).addNotifier(std::move(f));
1065 }
1066
1067 bool isValid() const
1068 {
1069 return aliasedProperty() != nullptr;
1070 }
1071 QT_WARNING_POP
1072};
1073#endif // QT_DEPRECATED_SINCE(6, 6)
1074
1075template<typename Class, typename T, auto Offset, auto Signal = nullptr>
1077{
1079 static bool constexpr HasSignal = !std::is_same_v<decltype(Signal), std::nullptr_t>;
1080 using SignalTakesValue = std::is_invocable<decltype(Signal), Class, T>;
1081 Class *owner()
1082 {
1083 char *that = reinterpret_cast<char *>(this);
1084 return reinterpret_cast<Class *>(that - QtPrivate::detail::getOffset(Offset));
1085 }
1086 const Class *owner() const
1087 {
1088 char *that = const_cast<char *>(reinterpret_cast<const char *>(this));
1089 return reinterpret_cast<Class *>(that - QtPrivate::detail::getOffset(Offset));
1090 }
1091 static void signalCallBack(QUntypedPropertyData *o)
1092 {
1093 QObjectBindableProperty *that = static_cast<QObjectBindableProperty *>(o);
1094 if constexpr (HasSignal) {
1095 if constexpr (SignalTakesValue::value)
1096 (that->owner()->*Signal)(that->valueBypassingBindings());
1097 else
1098 (that->owner()->*Signal)();
1099 }
1100 }
1101public:
1106
1108 explicit QObjectBindableProperty(const T &initialValue) : QPropertyData<T>(initialValue) {}
1109 explicit QObjectBindableProperty(T &&initialValue) : QPropertyData<T>(std::move(initialValue)) {}
1110 explicit QObjectBindableProperty(const QPropertyBinding<T> &binding)
1112 { setBinding(binding); }
1113#ifndef Q_QDOC
1114 template <typename Functor>
1115 explicit QObjectBindableProperty(Functor &&f, const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION,
1116 typename std::enable_if_t<std::is_invocable_r_v<T, Functor&>> * = nullptr)
1117 : QObjectBindableProperty(QPropertyBinding<T>(std::forward<Functor>(f), location))
1118 {}
1119#else
1120 template <typename Functor>
1121 explicit QObjectBindableProperty(Functor &&f);
1122#endif
1123
1124 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>)
1125 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>)
1126 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>)
1127
1129 {
1131 return this->val;
1132 }
1133
1135 {
1136 if constexpr (QTypeTraits::is_dereferenceable_v<T>) {
1137 return value();
1138 } else if constexpr (std::is_pointer_v<T>) {
1139 value();
1140 return this->val;
1141 } else {
1142 return;
1143 }
1144 }
1145
1147 {
1148 return value();
1149 }
1150
1152 {
1153 return value();
1154 }
1155
1157 {
1158 auto *bd = qGetBindingStorage(owner())->bindingData(this);
1159 if (bd)
1160 bd->removeBinding();
1161 if (this->val == t)
1162 return;
1163 this->val = t;
1164 notify(bd);
1165 }
1166
1167 void notify() {
1168 auto *bd = qGetBindingStorage(owner())->bindingData(this);
1169 notify(bd);
1170 }
1171
1173 {
1174 auto *bd = qGetBindingStorage(owner())->bindingData(this);
1175 if (bd)
1176 bd->removeBinding();
1177 if (this->val == t)
1178 return;
1179 this->val = std::move(t);
1180 notify(bd);
1181 }
1182
1184 {
1186 return *this;
1187 }
1188
1190 {
1192 return *this;
1193 }
1194
1201
1203 {
1205 return false;
1206 setBinding(static_cast<const QPropertyBinding<T> &>(newBinding));
1207 return true;
1208 }
1209
1210#ifndef Q_QDOC
1211 template <typename Functor>
1218#else
1219 template <typename Functor>
1221#endif
1222
1223 bool hasBinding() const
1224 {
1225 auto *bd = qGetBindingStorage(owner())->bindingData(this);
1226 return bd && bd->binding() != nullptr;
1227 }
1228
1230 {
1231 auto *bd = qGetBindingStorage(owner())->bindingData(this);
1232 return static_cast<QPropertyBinding<T> &&>(QUntypedPropertyBinding(bd ? bd->binding() : nullptr));
1233 }
1234
1236 {
1237 return setBinding(QPropertyBinding<T>());
1238 }
1239
1240 template<typename Functor>
1242 {
1243 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
1244 return QPropertyChangeHandler<Functor>(*this, std::move(f));
1245 }
1246
1247 template<typename Functor>
1249 {
1250 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
1251 f();
1252 return onValueChanged(std::move(f));
1253 }
1254
1255 template<typename Functor>
1257 {
1258 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
1259 return QPropertyNotifier(*this, std::move(f));
1260 }
1261
1263 {
1264 auto *storage = const_cast<QBindingStorage *>(qGetBindingStorage(owner()));
1265 return *storage->bindingData(const_cast<ThisType *>(this), true);
1266 }
1267private:
1268 template <typename Ty = T, std::enable_if_t<QTypeTraits::has_operator_equal_v<Ty>>* = nullptr>
1270 {
1271 return lhs.value() == rhs.value();
1272 }
1273
1274 template <typename Ty = T, std::enable_if_t<QTypeTraits::has_operator_equal_v<Ty>>* = nullptr>
1275 friend bool comparesEqual(const QObjectBindableProperty &lhs, const T &rhs)
1276 {
1277 return lhs.value() == rhs;
1278 }
1279
1281 {
1282 if (binding)
1284 if constexpr (HasSignal) {
1285 if constexpr (SignalTakesValue::value)
1286 (owner()->*Signal)(this->valueBypassingBindings());
1287 else
1288 (owner()->*Signal)();
1289 }
1290 }
1291};
1292
1293#define QT_OBJECT_BINDABLE_PROPERTY_3(Class, Type, name)
1294 static constexpr size_t _qt_property_##name##_offset() {
1295 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1296 return offsetof(Class, name);
1297 QT_WARNING_POP
1298 }
1299 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, nullptr> name;
1300
1301#define QT_OBJECT_BINDABLE_PROPERTY_4(Class, Type, name, Signal)
1302 static constexpr size_t _qt_property_##name##_offset() {
1303 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1304 return offsetof(Class, name);
1305 QT_WARNING_POP
1306 }
1307 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, Signal> name;
1308
1309#define Q_OBJECT_BINDABLE_PROPERTY(...)
1310 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1311 QT_OVERLOADED_MACRO(QT_OBJECT_BINDABLE_PROPERTY, __VA_ARGS__)
1312 QT_WARNING_POP
1313
1314#define QT_OBJECT_BINDABLE_PROPERTY_WITH_ARGS_4(Class, Type, name, value)
1315 static constexpr size_t _qt_property_##name##_offset()
1316 {
1317 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1318 return offsetof(Class, name);
1319 QT_WARNING_POP
1320 }
1321 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, nullptr> name =
1322 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, nullptr>(
1323 value);
1324
1325#define QT_OBJECT_BINDABLE_PROPERTY_WITH_ARGS_5(Class, Type, name, value, Signal)
1326 static constexpr size_t _qt_property_##name##_offset()
1327 {
1328 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1329 return offsetof(Class, name);
1330 QT_WARNING_POP
1331 }
1332 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, Signal> name =
1333 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, Signal>(
1334 value);
1335
1336#define Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(...)
1337 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1338 QT_OVERLOADED_MACRO(QT_OBJECT_BINDABLE_PROPERTY_WITH_ARGS, __VA_ARGS__)
1339 QT_WARNING_POP
1340
1341template<typename Class, typename T, auto Offset, auto Getter>
1343{
1344 Class *owner()
1345 {
1346 char *that = reinterpret_cast<char *>(this);
1347 return reinterpret_cast<Class *>(that - QtPrivate::detail::getOffset(Offset));
1348 }
1349 const Class *owner() const
1350 {
1351 char *that = const_cast<char *>(reinterpret_cast<const char *>(this));
1352 return reinterpret_cast<Class *>(that - QtPrivate::detail::getOffset(Offset));
1353 }
1354
1355public:
1356 using value_type = T;
1358
1360
1362 {
1363 qGetBindingStorage(owner())->registerDependency(this);
1364 return (owner()->*Getter)();
1365 }
1366
1368 operator->() const
1369 {
1370 if constexpr (QTypeTraits::is_dereferenceable_v<T>)
1371 return value();
1372 else
1373 return;
1374 }
1375
1377 {
1378 return value();
1379 }
1380
1382 {
1383 return value();
1384 }
1385
1386 constexpr bool hasBinding() const { return false; }
1387
1388 template<typename Functor>
1390 {
1391 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
1392 return QPropertyChangeHandler<Functor>(*this, std::move(f));
1393 }
1394
1395 template<typename Functor>
1397 {
1398 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
1399 f();
1400 return onValueChanged(std::move(f));
1401 }
1402
1403 template<typename Functor>
1405 {
1406 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
1407 return QPropertyNotifier(*this, std::move(f));
1408 }
1409
1411 {
1412 auto *storage = const_cast<QBindingStorage *>(qGetBindingStorage(owner()));
1413 return *storage->bindingData(const_cast<QObjectComputedProperty *>(this), true);
1414 }
1415
1416 void notify() {
1417 // computed property can't store a binding, so there's nothing to mark
1418 auto *storage = const_cast<QBindingStorage *>(qGetBindingStorage(owner()));
1419 auto bd = storage->bindingData(const_cast<QObjectComputedProperty *>(this), false);
1420 if (bd)
1422 }
1423};
1424
1425#define Q_OBJECT_COMPUTED_PROPERTY(Class, Type, name, ...)
1426 static constexpr size_t _qt_property_##name##_offset() {
1427 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1428 return offsetof(Class, name);
1429 QT_WARNING_POP
1430 }
1431 QObjectComputedProperty<Class, Type, Class::_qt_property_##name##_offset, __VA_ARGS__> name;
1432
1433#undef QT_SOURCE_LOCATION_NAMESPACE
1434
1435QT_END_NAMESPACE
1436
1437#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:887
QPropertyBinding< T > binding() const
Returns the currently set binding of the underlying property.
Definition qproperty.h:891
T value() const
Returns the underlying property's current value.
Definition qproperty.h:929
void setValue(const T &value)
Sets the underlying property's value to value.
Definition qproperty.h:939
friend class QPropertyAlias
Definition qproperty.h:867
QBindable(QObject *obj, const QMetaProperty &property)
Definition qproperty.h:881
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:918
QBindable(const QUntypedBindable &b)
Definition qproperty.h:873
QPropertyBinding< T > setBinding(const QPropertyBinding< T > &binding)
Sets the underlying property's binding to binding.
Definition qproperty.h:902
QBindable(QObject *obj, const char *property)
Definition qproperty.h:884
QPropertyBinding< T > takeBinding()
Removes the currently set binding of the underlying property and returns it.
Definition qproperty.h:896
\inmodule QtCore
\inmodule QtCore
Definition qproperty.h:1077
QObjectBindableProperty(const T &initialValue)
Constructs a property with the provided initialValue.
Definition qproperty.h:1108
QObjectBindableProperty()=default
typename QPropertyData< T >::rvalue_ref rvalue_ref
Definition qproperty.h:1104
typename QPropertyData< T >::value_type value_type
Definition qproperty.h:1102
QObjectBindableProperty(T &&initialValue)
Move-Constructs a property with the provided initialValue.
Definition qproperty.h:1109
typename QPropertyData< T >::arrow_operator_result arrow_operator_result
Definition qproperty.h:1105
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:1115
QObjectBindableProperty(const QPropertyBinding< T > &binding)
Definition qproperty.h:1110
typename QPropertyData< T >::parameter_type parameter_type
Definition qproperty.h:1103
\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:1343
QObjectComputedProperty()=default
parameter_type value() const
Definition qproperty.h:1361
\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:731
QUntypedPropertyBinding binding() const
Returns the underlying property's binding if there is any, or a default constructed QUntypedPropertyB...
Definition qproperty.h:811
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:755
bool hasBinding() const
Returns true if the underlying property has a binding.
Definition qproperty.h:841
constexpr QUntypedBindable()=default
Default-constructs a QUntypedBindable.
QMetaType metaType() const
Definition qproperty.h:846
const QtPrivate::QBindableInterface * iface
Definition qproperty.h:735
QPropertyChangeHandler< Functor > onValueChanged(Functor f) const
Installs f as a change handler.
Definition qproperty.h:789
QUntypedPropertyBinding takeBinding()
Removes the currently set binding from the property and returns it.
Definition qproperty.h:760
QPropertyNotifier addNotifier(Functor f)
Installs f as a change handler.
Definition qproperty.h:804
QUntypedPropertyData * data
Definition qproperty.h:734
bool isBindable() const
Definition qproperty.h:752
bool isValid() const
Returns true if the QUntypedBindable is valid.
Definition qproperty.h:751
bool setBinding(const QUntypedPropertyBinding &binding)
Sets the underlying property's binding to binding.
Definition qproperty.h:822
bool isReadOnly() const
Definition qproperty.h:753
QUntypedBindable(Property *p)
Constructs a QUntypedBindable from the property property.
Definition qproperty.h:746
QPropertyChangeHandler< Functor > subscribe(Functor f) const
Behaves like a call to f followed by onValueChanged(f),.
Definition qproperty.h:797
constexpr QUntypedBindable(QUntypedPropertyData *d, const QtPrivate::QBindableInterface *i)
Definition qproperty.h:736
void observe(QPropertyObserver *observer) const
Definition qproperty.h:777
\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:1336
#define QT_PROPERTY_DEFAULT_BINDING_LOCATION
Definition qproperty.h:48
#define Q_OBJECT_COMPUTED_PROPERTY(Class, Type, name, ...)
Definition qproperty.h:1425
#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