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