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#if QT_CORE_REMOVED_SINCE(6, 12)
186 explicit QUntypedPropertyBinding(QPropertyBindingPrivate *priv);
187#endif
188//private:
189 // the following public classes access this constructor from inline code
190 template<typename Class, typename T, auto Offset, auto Signal> friend class QObjectBindableProperty;
191 template<typename T> friend class QBindable;
192 template<typename T> friend class QProperty;
193 explicit QUntypedPropertyBinding(void *priv);
194private:
195 friend class QtPrivate::QPropertyBindingData;
196 friend class QPropertyBindingPrivate;
197 template <typename> friend class QPropertyBinding;
198 QPropertyBindingPrivatePtr d;
199};
200
201template <typename PropertyType>
203{
204
205public:
206 QPropertyBinding() = default;
207
208 template<typename Functor>
209 QPropertyBinding(Functor &&f, const QPropertyBindingSourceLocation &location)
211 {}
212
213
214 // Internal
215 explicit QPropertyBinding(const QUntypedPropertyBinding &binding)
217 {}
218};
219
220namespace Qt {
221 template <typename Functor>
222 auto makePropertyBinding(Functor &&f, const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION,
223 std::enable_if_t<std::is_invocable_v<Functor>> * = nullptr)
224 {
225 return QPropertyBinding<std::invoke_result_t<Functor>>(std::forward<Functor>(f), location);
226 }
227}
228
229struct QPropertyObserverPrivate;
231class QPropertyObserver;
232
234{
235public:
236 // Internal
238 ObserverNotifiesBinding, // observer was installed to notify bindings that obsverved property changed
239 ObserverNotifiesChangeHandler, // observer is a change handler, which runs on every change
240 ObserverIsPlaceholder, // the observer before this one is currently evaluated in QPropertyObserver::notifyObservers.
241#if QT_DEPRECATED_SINCE(6, 6)
242 ObserverIsAlias QT_DEPRECATED_VERSION_X_6_6("Use QProperty and add a binding to the target.")
243#endif
244 };
245protected:
246 using ChangeHandler = void (*)(QPropertyObserver*, QUntypedPropertyData *);
247
248private:
251 friend class QPropertyObserver;
254 friend class QPropertyBindingPrivate;
255
256 QTaggedPointer<QPropertyObserver, ObserverTag> next;
257 // prev is a pointer to the "next" element within the previous node, or to the "firstObserverPtr" if it is the
258 // first node.
259 QtPrivate::QTagPreservingPointerToPointer<QPropertyObserver, ObserverTag> prev;
260
261 union {
265 };
266};
267
268class Q_CORE_EXPORT QPropertyObserver : public QPropertyObserverBase
269{
270public:
271 constexpr QPropertyObserver() = default;
272 QPropertyObserver(QPropertyObserver &&other) noexcept;
273 QPropertyObserver &operator=(QPropertyObserver &&other) noexcept;
274 ~QPropertyObserver();
275
276 template <typename Property, QtPrivate::IsUntypedPropertyData<Property> = true>
277 void setSource(const Property &property)
278 { setSource(property.bindingData()); }
279 void setSource(const QtPrivate::QPropertyBindingData &property);
280
281protected:
282 QPropertyObserver(ChangeHandler changeHandler);
283#if QT_DEPRECATED_SINCE(6, 6)
284 QT_DEPRECATED_VERSION_X_6_6("This constructor was only meant for internal use. Use QProperty and add a binding to the target.")
285 QPropertyObserver(QUntypedPropertyData *aliasedPropertyPtr);
286#endif
287
288 QUntypedPropertyData *aliasedProperty() const
289 {
290 return aliasData;
291 }
292
293private:
294
295 QPropertyObserver(const QPropertyObserver &) = delete;
296 QPropertyObserver &operator=(const QPropertyObserver &) = delete;
297
298};
299
300template <typename Functor>
327
329{
330 std::function<void()> m_handler;
331public:
333 QPropertyNotifier() = default;
334 template<typename Functor>
344
345 template <typename Functor, typename Property,
357};
358
359template <typename T>
360class QProperty : public QPropertyData<T>
361{
362 QtPrivate::QPropertyBindingData d;
363 bool is_equal(const T &v)
364 {
365 if constexpr (QTypeTraits::has_operator_equal_v<T>) {
366 if (v == this->val)
367 return true;
368 }
369 return false;
370 }
371
372 template <typename U, typename = void>
373 struct has_operator_equal_to : std::false_type{};
374
375 template <typename U>
376 struct has_operator_equal_to<U, std::void_t<decltype(bool(std::declval<const T&>() == std::declval<const U&>()))>>
377 : std::true_type{};
378
379 template <typename U>
380 static constexpr bool has_operator_equal_to_v =
382
383public:
384 using value_type = typename QPropertyData<T>::value_type;
386 using rvalue_ref = typename QPropertyData<T>::rvalue_ref;
388
389 QProperty() = default;
390 explicit QProperty(parameter_type initialValue) : QPropertyData<T>(initialValue) {}
391 explicit QProperty(rvalue_ref initialValue) : QPropertyData<T>(std::move(initialValue)) {}
392 explicit QProperty(const QPropertyBinding<T> &binding)
393 : QProperty()
394 { setBinding(binding); }
395#ifndef Q_QDOC
396 template <typename Functor>
397 explicit QProperty(Functor &&f, const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION,
398 typename std::enable_if_t<std::is_invocable_r_v<T, Functor&>> * = nullptr)
399 : QProperty(QPropertyBinding<T>(std::forward<Functor>(f), location))
400 {}
401#else
402 template <typename Functor>
403 explicit QProperty(Functor &&f);
404#endif
405 ~QProperty() = default;
406
407 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>)
408 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>)
409 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>)
410
411 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>)
412 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>)
413
414 // Explicitly delete op==(QProperty<T>, QProperty<U>) for different T & U.
415 // We do not want implicit conversions here!
416 // However, GCC complains about using a default template argument in a
417 // friend declaration, while Clang and MSVC are fine. So, skip GCC here.
418#if !defined(Q_CC_GNU) || defined(Q_CC_CLANG)
419#define QPROPERTY_DECL_DELETED_EQ_OP
420 Q_DECL_EQ_DELETE_X("Call .value() on one of the properties explicitly.")
421 template <typename U, std::enable_if_t<!std::is_same_v<T, U>>* = nullptr>
423 template <typename U, std::enable_if_t<!std::is_same_v<T, U>>* = nullptr>
424 friend void operator!=(const QProperty &, const QProperty<U> &) QPROPERTY_DECL_DELETED_EQ_OP;
425#undef QPROPERTY_DECL_DELETED_EQ_OP
426#endif // !defined(Q_CC_GNU) || defined(Q_CC_CLANG)
427
429 {
430 d.registerWithCurrentlyEvaluatingBinding();
431 return this->val;
432 }
433
435 {
436 if constexpr (QTypeTraits::is_dereferenceable_v<T>) {
437 return value();
438 } else if constexpr (std::is_pointer_v<T>) {
439 value();
440 return this->val;
441 } else {
442 return;
443 }
444 }
445
447 {
448 return value();
449 }
450
452 {
453 return value();
454 }
455
456 void setValue(rvalue_ref newValue)
457 {
458 d.removeBinding();
459 if (is_equal(newValue))
460 return;
461 this->val = std::move(newValue);
462 notify();
463 }
464
466 {
467 d.removeBinding();
468 if (is_equal(newValue))
469 return;
470 this->val = newValue;
471 notify();
472 }
473
475 {
476 setValue(std::move(newValue));
477 return *this;
478 }
479
481 {
482 setValue(newValue);
483 return *this;
484 }
485
487 {
488 return QPropertyBinding<T>(d.setBinding(newBinding, this));
489 }
490
491 bool setBinding(const QUntypedPropertyBinding &newBinding)
492 {
493 if (!newBinding.isNull() && newBinding.valueMetaType().id() != qMetaTypeId<T>())
494 return false;
495 setBinding(static_cast<const QPropertyBinding<T> &>(newBinding));
496 return true;
497 }
498
499#ifndef Q_QDOC
500 template <typename Functor>
502 const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION,
503 std::enable_if_t<std::is_invocable_v<Functor>> * = nullptr)
504 {
505 return setBinding(Qt::makePropertyBinding(std::forward<Functor>(f), location));
506 }
507#else
508 template <typename Functor>
510#endif
511
512 bool hasBinding() const { return d.hasBinding(); }
513
515 {
516 return QPropertyBinding<T>(QUntypedPropertyBinding(d.binding()));
517 }
518
520 {
521 return QPropertyBinding<T>(d.setBinding(QUntypedPropertyBinding(), this));
522 }
523
524 template<typename Functor>
526 {
527 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
528 return QPropertyChangeHandler<Functor>(*this, 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 f();
536 return onValueChanged(std::move(f));
537 }
538
539 template<typename Functor>
541 {
542 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
543 return QPropertyNotifier(*this, std::move(f));
544 }
545
546 const QtPrivate::QPropertyBindingData &bindingData() const { return d; }
547private:
548 template <typename Ty = T, std::enable_if_t<QTypeTraits::has_operator_equal_v<Ty>>* = nullptr>
549 friend bool comparesEqual(const QProperty &lhs, const QProperty &rhs)
550 {
551 return lhs.value() == rhs.value();
552 }
553
554 template <typename Ty = T, std::enable_if_t<QTypeTraits::has_operator_equal_v<Ty>>* = nullptr>
555 friend bool comparesEqual(const QProperty &lhs, const T &rhs)
556 {
557 return lhs.value() == rhs;
558 }
559
560 template <typename U, std::enable_if_t<has_operator_equal_to_v<U>>* = nullptr>
561 friend bool comparesEqual(const QProperty &lhs, const U &rhs)
562 {
563 return lhs.value() == rhs;
564 }
565
566 void notify()
567 {
568 d.notifyObservers(this);
569 }
570
572};
573
574namespace Qt {
575 template <typename PropertyType>
576 QPropertyBinding<PropertyType> makePropertyBinding(const QProperty<PropertyType> &otherProperty,
577 const QPropertyBindingSourceLocation &location =
579 {
580 return Qt::makePropertyBinding([&otherProperty]() -> PropertyType { return otherProperty; }, location);
581 }
582}
583
584
585namespace QtPrivate
586{
587
589{
590 using Getter = void (*)(const QUntypedPropertyData *d, void *value);
591 using Setter = void (*)(QUntypedPropertyData *d, const void *value);
595 using SetObserver = void (*)(const QUntypedPropertyData *d, QPropertyObserver *observer);
596 using GetMetaType = QMetaType (*)();
604
605 static constexpr quintptr MetaTypeAccessorFlag = 0x1;
606};
607
608template<typename Property, typename = void>
610{
611 using T = typename Property::value_type;
612public:
613 // interface for computed properties. Those do not have a binding()/setBinding() method, but one can
614 // install observers on them.
615 static constexpr QBindableInterface iface = {
616 [](const QUntypedPropertyData *d, void *value) -> void
617 { *static_cast<T*>(value) = static_cast<const Property *>(d)->value(); },
618 nullptr,
619 nullptr,
620 nullptr,
622 { return Qt::makePropertyBinding([d]() -> T { return static_cast<const Property *>(d)->value(); }, location); },
624 { observer->setSource(static_cast<const Property *>(d)->bindingData()); },
625 []() { return QMetaType::fromType<T>(); }
626 };
627};
628
629template<typename Property>
631{
632 using T = typename Property::value_type;
633public:
634 // A bindable created from a const property results in a read-only interface, too.
635 static constexpr QBindableInterface iface = {
636
637 [](const QUntypedPropertyData *d, void *value) -> void
638 { *static_cast<T*>(value) = static_cast<const Property *>(d)->value(); },
639 /*setter=*/nullptr,
641 { return static_cast<const Property *>(d)->binding(); },
642 /*setBinding=*/nullptr,
644 { return Qt::makePropertyBinding([d]() -> T { return static_cast<const Property *>(d)->value(); }, location); },
646 { observer->setSource(static_cast<const Property *>(d)->bindingData()); },
647 []() { return QMetaType::fromType<T>(); }
648 };
649};
650
651template<typename Property>
653{
654 using T = typename Property::value_type;
655public:
656 static constexpr QBindableInterface iface = {
657 [](const QUntypedPropertyData *d, void *value) -> void
658 { *static_cast<T*>(value) = static_cast<const Property *>(d)->value(); },
659 [](QUntypedPropertyData *d, const void *value) -> void
660 { static_cast<Property *>(d)->setValue(*static_cast<const T*>(value)); },
662 { return static_cast<const Property *>(d)->binding(); },
664 { return static_cast<Property *>(d)->setBinding(static_cast<const QPropertyBinding<T> &>(binding)); },
666 { return Qt::makePropertyBinding([d]() -> T { return static_cast<const Property *>(d)->value(); }, location); },
668 { observer->setSource(static_cast<const Property *>(d)->bindingData()); },
669 []() { return QMetaType::fromType<T>(); }
670 };
671};
672
673}
674
675namespace QtPrivate {
676// used in Q(Untyped)Bindable to print warnings about various binding errors
677namespace BindableWarnings {
679Q_CORE_EXPORT void printUnsuitableBindableWarning(QAnyStringView prefix, Reason reason);
680Q_CORE_EXPORT void printMetaTypeMismatch(QMetaType actual, QMetaType expected);
681}
682
684Q_CORE_EXPORT void getter(const QUntypedPropertyData *d, void *value);
685Q_CORE_EXPORT void setter(QUntypedPropertyData *d, const void *value);
686Q_CORE_EXPORT QUntypedPropertyBinding getBinding(const QUntypedPropertyData *d);
687Q_CORE_EXPORT bool bindingWrapper(QMetaType type, QUntypedPropertyData *d,
688 QtPrivate::QPropertyBindingFunction binding,
689 QUntypedPropertyData *temp, void *value);
690Q_CORE_EXPORT QUntypedPropertyBinding setBinding(QUntypedPropertyData *d,
693Q_CORE_EXPORT void setObserver(const QUntypedPropertyData *d, QPropertyObserver *observer);
694
695template<typename T>
696bool bindingWrapper(QMetaType type, QUntypedPropertyData *d,
697 QtPrivate::QPropertyBindingFunction binding)
698{
699 struct Data : QPropertyData<T>
700 {
701 void *data() { return &this->val; }
702 } temp;
703 return bindingWrapper(type, d, binding, &temp, temp.data());
704}
705
706template<typename T>
707QUntypedPropertyBinding setBinding(QUntypedPropertyData *d, const QUntypedPropertyBinding &binding)
708{
709 return setBinding(d, binding, &bindingWrapper<T>);
710}
711
712template<typename T>
713QUntypedPropertyBinding makeBinding(const QUntypedPropertyData *d,
714 const QPropertyBindingSourceLocation &location)
715{
716 return Qt::makePropertyBinding(
717 [d]() -> T {
718 T r;
719 getter(d, &r);
720 return r;
721 },
722 location);
723}
724
725template<class T>
726inline constexpr QBindableInterface iface = {
727#ifdef QT_NO_DATA_RELOCATION
728 // On windows the address of a dllimported function can't be relocated here.
729 // MSVC automatically generates a trampoline, but clang won't, so do it explicitly.
730 [](const QUntypedPropertyData *d, void *value) { getter(d, value); },
731 [](QUntypedPropertyData *d, const void *value) { setter(d, value); },
732 [](const QUntypedPropertyData *d) -> QUntypedPropertyBinding { return getBinding(d); },
733 &setBinding<T>,
734 &makeBinding<T>,
737#else
738 &getter,
739 &setter,
740 &getBinding,
741 &setBinding<T>,
742 &makeBinding<T>,
745#endif
746};
747}
748}
749
751{
752 friend struct QUntypedBindablePrivate; // allows access to internal data
753protected:
756 constexpr QUntypedBindable(QUntypedPropertyData *d, const QtPrivate::QBindableInterface *i)
757 : data(d), iface(i)
758 {}
759
762
763public:
764 constexpr QUntypedBindable() = default;
765 template<typename Property>
766 QUntypedBindable(Property *p)
767 : data(const_cast<std::remove_cv_t<Property> *>(p)),
769 { Q_ASSERT(data && iface); }
770
771 bool isValid() const { return data != nullptr; }
772 bool isBindable() const { return iface && iface->getBinding; }
773 bool isReadOnly() const { return !(iface && iface->setBinding && iface->setObserver); }
774
775 QUntypedPropertyBinding makeBinding(const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION) const
776 {
777 return iface ? iface->makeBinding(data, location) : QUntypedPropertyBinding();
778 }
779
781 {
782 if (!iface)
783 return QUntypedPropertyBinding {};
784 // We do not have a dedicated takeBinding function pointer in the interface
785 // therefore we synthesize takeBinding by retrieving the binding with binding
786 // and calling setBinding with a default constructed QUntypedPropertyBinding
787 // afterwards.
788 if (!(iface->getBinding && iface->setBinding))
789 return QUntypedPropertyBinding {};
790 return [&] {
791 QUntypedPropertyBinding binding = iface->getBinding(data);
792 iface->setBinding(data, QUntypedPropertyBinding{});
793 return binding;
794 }();
795 }
796
797 void observe(QPropertyObserver *observer) const
798 {
799 if (iface)
800 iface->setObserver(data, observer);
801#ifndef QT_NO_DEBUG
802 else
805#endif
806 }
807
808 template<typename Functor>
809 QPropertyChangeHandler<Functor> onValueChanged(Functor f) const
810 {
811 QPropertyChangeHandler<Functor> handler(std::move(f));
812 observe(&handler);
813 return handler;
814 }
815
816 template<typename Functor>
817 QPropertyChangeHandler<Functor> subscribe(Functor f) const
818 {
819 f();
820 return onValueChanged(std::move(f));
821 }
822
823 template<typename Functor>
825 {
826 QPropertyNotifier handler(std::move(f));
827 observe(&handler);
828 return handler;
829 }
830
832 {
833 if (!isBindable()) {
834#ifndef QT_NO_DEBUG
837#endif
838 return QUntypedPropertyBinding();
839 }
840 return iface->getBinding(data);
841 }
842 bool setBinding(const QUntypedPropertyBinding &binding)
843 {
844 if (isReadOnly()) {
845#ifndef QT_NO_DEBUG
848 QtPrivate::BindableWarnings::printUnsuitableBindableWarning("setBinding: Could not set binding via bindable interface.", errorType);
849#endif
850 return false;
851 }
852 if (!binding.isNull() && binding.valueMetaType() != metaType()) {
853#ifndef QT_NO_DEBUG
854 QtPrivate::BindableWarnings::printMetaTypeMismatch(metaType(), binding.valueMetaType());
855#endif
856 return false;
857 }
858 iface->setBinding(data, binding);
859 return true;
860 }
861 bool hasBinding() const
862 {
863 return !binding().isNull();
864 }
865
867 {
868 if (!(iface && data))
869 return QMetaType();
870 if (iface->metaType)
871 return iface->metaType();
872 // ### Qt 7: Change the metatype function to take data as its argument
873 // special casing for QML's proxy bindable: allow multiplexing in the getter
874 // function to retrieve the metatype from data
875 Q_ASSERT(iface->getter);
876 QMetaType result;
877 iface->getter(data, reinterpret_cast<void *>(quintptr(&result) | QtPrivate::QBindableInterface::MetaTypeAccessorFlag));
878 return result;
879 }
880
881};
882
883template<typename T>
884class QBindable : public QUntypedBindable
885{
886 template<typename U>
887 friend class QPropertyAlias;
888 constexpr QBindable(QUntypedPropertyData *d, const QtPrivate::QBindableInterface *i)
889 : QUntypedBindable(d, i)
890 {}
891public:
892 using QUntypedBindable::QUntypedBindable;
894 {
895 if (iface && metaType() != QMetaType::fromType<T>()) {
896 data = nullptr;
897 iface = nullptr;
898 }
899 }
900
901 explicit QBindable(QObject *obj, const QMetaProperty &property)
902 : QUntypedBindable(obj, property, &QtPrivate::PropertyAdaptorSlotObjectHelpers::iface<T>) {}
903
904 explicit QBindable(QObject *obj, const char *property)
905 : QUntypedBindable(obj, property, &QtPrivate::PropertyAdaptorSlotObjectHelpers::iface<T>) {}
906
907 QPropertyBinding<T> makeBinding(const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION) const
908 {
909 return static_cast<QPropertyBinding<T> &&>(QUntypedBindable::makeBinding(location));
910 }
912 {
913 return static_cast<QPropertyBinding<T> &&>(QUntypedBindable::binding());
914 }
915
917 {
918 return static_cast<QPropertyBinding<T> &&>(QUntypedBindable::takeBinding());
919 }
920
921 using QUntypedBindable::setBinding;
923 {
924 Q_ASSERT(!iface || binding.isNull() || binding.valueMetaType() == metaType());
925
926 if (iface && iface->setBinding)
927 return static_cast<QPropertyBinding<T> &&>(iface->setBinding(data, binding));
928#ifndef QT_NO_DEBUG
929 if (!iface)
931 else
933#endif
934 return QPropertyBinding<T>();
935 }
936#ifndef Q_QDOC
937 template <typename Functor>
939 const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION,
940 std::enable_if_t<std::is_invocable_v<Functor>> * = nullptr)
941 {
942 return setBinding(Qt::makePropertyBinding(std::forward<Functor>(f), location));
943 }
944#else
945 template <typename Functor>
946 QPropertyBinding<T> setBinding(Functor f);
947#endif
948
949 T value() const
950 {
951 if (iface) {
952 T result;
953 iface->getter(data, &result);
954 return result;
955 }
956 return T{};
957 }
958
959 void setValue(const T &value)
960 {
961 if (iface && iface->setter)
962 iface->setter(data, &value);
963 }
964};
965
966#if QT_DEPRECATED_SINCE(6, 6)
967template<typename T>
968class QT_DEPRECATED_VERSION_X_6_6("Class was only meant for internal use, use a QProperty and add a binding to the target")
969QPropertyAlias : public QPropertyObserver
970{
971 Q_DISABLE_COPY_MOVE(QPropertyAlias)
972 const QtPrivate::QBindableInterface *iface = nullptr;
973
974public:
975 QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
976 QPropertyAlias(QProperty<T> *property)
977 : QPropertyObserver(property),
978 iface(&QtPrivate::QBindableInterfaceForProperty<QProperty<T>>::iface)
979 {
980 if (iface)
981 iface->setObserver(aliasedProperty(), this);
982 }
983
984 template <typename Property, QtPrivate::IsUntypedPropertyData<Property> = true>
985 QPropertyAlias(Property *property)
986 : QPropertyObserver(property),
987 iface(&QtPrivate::QBindableInterfaceForProperty<Property>::iface)
988 {
989 if (iface)
990 iface->setObserver(aliasedProperty(), this);
991 }
992
993 QPropertyAlias(QPropertyAlias<T> *alias)
994 : QPropertyObserver(alias->aliasedProperty()),
995 iface(alias->iface)
996 {
997 if (iface)
998 iface->setObserver(aliasedProperty(), this);
999 }
1000
1001 QPropertyAlias(const QBindable<T> &property)
1002 : QPropertyObserver(property.data),
1003 iface(property.iface)
1004 {
1005 if (iface)
1006 iface->setObserver(aliasedProperty(), this);
1007 }
1008
1009 T value() const
1010 {
1011 T t = T();
1012 if (auto *p = aliasedProperty())
1013 iface->getter(p, &t);
1014 return t;
1015 }
1016
1017 operator T() const { return value(); }
1018
1019 void setValue(const T &newValue)
1020 {
1021 if (auto *p = aliasedProperty())
1022 iface->setter(p, &newValue);
1023 }
1024
1025 QPropertyAlias<T> &operator=(const T &newValue)
1026 {
1027 setValue(newValue);
1028 return *this;
1029 }
1030
1031 QPropertyBinding<T> setBinding(const QPropertyBinding<T> &newBinding)
1032 {
1033 return QBindable<T>(aliasedProperty(), iface).setBinding(newBinding);
1034 }
1035
1036 bool setBinding(const QUntypedPropertyBinding &newBinding)
1037 {
1038 return QBindable<T>(aliasedProperty(), iface).setBinding(newBinding);
1039 }
1040
1041#ifndef Q_QDOC
1042 template <typename Functor>
1043 QPropertyBinding<T> setBinding(Functor &&f,
1044 const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION,
1045 std::enable_if_t<std::is_invocable_v<Functor>> * = nullptr)
1046 {
1047 return setBinding(Qt::makePropertyBinding(std::forward<Functor>(f), location));
1048 }
1049#else
1050 template <typename Functor>
1051 QPropertyBinding<T> setBinding(Functor f);
1052#endif
1053
1054 bool hasBinding() const
1055 {
1056 return QBindable<T>(aliasedProperty(), iface).hasBinding();
1057 }
1058
1059 QPropertyBinding<T> binding() const
1060 {
1061 return QBindable<T>(aliasedProperty(), iface).binding();
1062 }
1063
1064 QPropertyBinding<T> takeBinding()
1065 {
1066 return QBindable<T>(aliasedProperty(), iface).takeBinding();
1067 }
1068
1069 template<typename Functor>
1070 QPropertyChangeHandler<Functor> onValueChanged(Functor f)
1071 {
1072 return QBindable<T>(aliasedProperty(), iface).onValueChanged(std::move(f));
1073 }
1074
1075 template<typename Functor>
1076 QPropertyChangeHandler<Functor> subscribe(Functor f)
1077 {
1078 return QBindable<T>(aliasedProperty(), iface).subscribe(std::move(f));
1079 }
1080
1081 template<typename Functor>
1082 QPropertyNotifier addNotifier(Functor f)
1083 {
1084 return QBindable<T>(aliasedProperty(), iface).addNotifier(std::move(f));
1085 }
1086
1087 bool isValid() const
1088 {
1089 return aliasedProperty() != nullptr;
1090 }
1091 QT_WARNING_POP
1092};
1093#endif // QT_DEPRECATED_SINCE(6, 6)
1094
1095template<typename Class, typename T, auto Offset, auto Signal = nullptr>
1097{
1099 static bool constexpr HasSignal = !std::is_same_v<decltype(Signal), std::nullptr_t>;
1100 using SignalTakesValue = std::is_invocable<decltype(Signal), Class, T>;
1101 Class *owner()
1102 {
1103 char *that = reinterpret_cast<char *>(this);
1104 return reinterpret_cast<Class *>(that - QtPrivate::detail::getOffset(Offset));
1105 }
1106 const Class *owner() const
1107 {
1108 char *that = const_cast<char *>(reinterpret_cast<const char *>(this));
1109 return reinterpret_cast<Class *>(that - QtPrivate::detail::getOffset(Offset));
1110 }
1111 static void signalCallBack(QUntypedPropertyData *o)
1112 {
1113 QObjectBindableProperty *that = static_cast<QObjectBindableProperty *>(o);
1114 if constexpr (HasSignal) {
1115 if constexpr (SignalTakesValue::value)
1116 (that->owner()->*Signal)(that->valueBypassingBindings());
1117 else
1118 (that->owner()->*Signal)();
1119 }
1120 }
1121public:
1126
1128 explicit QObjectBindableProperty(const T &initialValue) : QPropertyData<T>(initialValue) {}
1129 explicit QObjectBindableProperty(T &&initialValue) : QPropertyData<T>(std::move(initialValue)) {}
1130 explicit QObjectBindableProperty(const QPropertyBinding<T> &binding)
1132 { setBinding(binding); }
1133#ifndef Q_QDOC
1134 template <typename Functor>
1135 explicit QObjectBindableProperty(Functor &&f, const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION,
1136 typename std::enable_if_t<std::is_invocable_r_v<T, Functor&>> * = nullptr)
1137 : QObjectBindableProperty(QPropertyBinding<T>(std::forward<Functor>(f), location))
1138 {}
1139#else
1140 template <typename Functor>
1141 explicit QObjectBindableProperty(Functor &&f);
1142#endif
1143
1144 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>)
1145 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>)
1146 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>)
1147
1149 {
1151 return this->val;
1152 }
1153
1155 {
1156 if constexpr (QTypeTraits::is_dereferenceable_v<T>) {
1157 return value();
1158 } else if constexpr (std::is_pointer_v<T>) {
1159 value();
1160 return this->val;
1161 } else {
1162 return;
1163 }
1164 }
1165
1167 {
1168 return value();
1169 }
1170
1172 {
1173 return value();
1174 }
1175
1177 {
1178 auto *bd = qGetBindingStorage(owner())->bindingData(this);
1179 if (bd)
1180 bd->removeBinding();
1181 if (this->val == t)
1182 return;
1183 this->val = t;
1184 notify(bd);
1185 }
1186
1187 void notify() {
1188 auto *bd = qGetBindingStorage(owner())->bindingData(this);
1189 notify(bd);
1190 }
1191
1193 {
1194 auto *bd = qGetBindingStorage(owner())->bindingData(this);
1195 if (bd)
1196 bd->removeBinding();
1197 if (this->val == t)
1198 return;
1199 this->val = std::move(t);
1200 notify(bd);
1201 }
1202
1204 {
1206 return *this;
1207 }
1208
1210 {
1212 return *this;
1213 }
1214
1221
1223 {
1225 return false;
1226 setBinding(static_cast<const QPropertyBinding<T> &>(newBinding));
1227 return true;
1228 }
1229
1230#ifndef Q_QDOC
1231 template <typename Functor>
1238#else
1239 template <typename Functor>
1241#endif
1242
1243 bool hasBinding() const
1244 {
1245 auto *bd = qGetBindingStorage(owner())->bindingData(this);
1246 return bd && bd->binding() != nullptr;
1247 }
1248
1250 {
1251 auto *bd = qGetBindingStorage(owner())->bindingData(this);
1252 return static_cast<QPropertyBinding<T> &&>(QUntypedPropertyBinding(bd ? bd->binding() : nullptr));
1253 }
1254
1256 {
1257 return setBinding(QPropertyBinding<T>());
1258 }
1259
1260 template<typename Functor>
1262 {
1263 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
1264 return QPropertyChangeHandler<Functor>(*this, std::move(f));
1265 }
1266
1267 template<typename Functor>
1269 {
1270 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
1271 f();
1272 return onValueChanged(std::move(f));
1273 }
1274
1275 template<typename Functor>
1277 {
1278 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
1279 return QPropertyNotifier(*this, std::move(f));
1280 }
1281
1283 {
1284 auto *storage = const_cast<QBindingStorage *>(qGetBindingStorage(owner()));
1285 return *storage->bindingData(const_cast<ThisType *>(this), true);
1286 }
1287private:
1288 template <typename Ty = T, std::enable_if_t<QTypeTraits::has_operator_equal_v<Ty>>* = nullptr>
1290 {
1291 return lhs.value() == rhs.value();
1292 }
1293
1294 template <typename Ty = T, std::enable_if_t<QTypeTraits::has_operator_equal_v<Ty>>* = nullptr>
1295 friend bool comparesEqual(const QObjectBindableProperty &lhs, const T &rhs)
1296 {
1297 return lhs.value() == rhs;
1298 }
1299
1301 {
1302 if (binding)
1304 if constexpr (HasSignal) {
1305 if constexpr (SignalTakesValue::value)
1306 (owner()->*Signal)(this->valueBypassingBindings());
1307 else
1308 (owner()->*Signal)();
1309 }
1310 }
1311};
1312
1313#define QT_OBJECT_BINDABLE_PROPERTY_3(Class, Type, name)
1314 static constexpr size_t _qt_property_##name##_offset() {
1315 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1316 return offsetof(Class, name);
1317 QT_WARNING_POP
1318 }
1319 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, nullptr> name;
1320
1321#define QT_OBJECT_BINDABLE_PROPERTY_4(Class, Type, name, Signal)
1322 static constexpr size_t _qt_property_##name##_offset() {
1323 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1324 return offsetof(Class, name);
1325 QT_WARNING_POP
1326 }
1327 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, Signal> name;
1328
1329#define Q_OBJECT_BINDABLE_PROPERTY(...)
1330 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1331 QT_OVERLOADED_MACRO(QT_OBJECT_BINDABLE_PROPERTY, __VA_ARGS__)
1332 QT_WARNING_POP
1333
1334#define QT_OBJECT_BINDABLE_PROPERTY_WITH_ARGS_4(Class, Type, name, value)
1335 static constexpr size_t _qt_property_##name##_offset()
1336 {
1337 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1338 return offsetof(Class, name);
1339 QT_WARNING_POP
1340 }
1341 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, nullptr> name =
1342 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, nullptr>(
1343 value);
1344
1345#define QT_OBJECT_BINDABLE_PROPERTY_WITH_ARGS_5(Class, Type, name, value, Signal)
1346 static constexpr size_t _qt_property_##name##_offset()
1347 {
1348 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1349 return offsetof(Class, name);
1350 QT_WARNING_POP
1351 }
1352 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, Signal> name =
1353 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, Signal>(
1354 value);
1355
1356#define Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(...)
1357 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1358 QT_OVERLOADED_MACRO(QT_OBJECT_BINDABLE_PROPERTY_WITH_ARGS, __VA_ARGS__)
1359 QT_WARNING_POP
1360
1361template<typename Class, typename T, auto Offset, auto Getter>
1363{
1364 Class *owner()
1365 {
1366 char *that = reinterpret_cast<char *>(this);
1367 return reinterpret_cast<Class *>(that - QtPrivate::detail::getOffset(Offset));
1368 }
1369 const Class *owner() const
1370 {
1371 char *that = const_cast<char *>(reinterpret_cast<const char *>(this));
1372 return reinterpret_cast<Class *>(that - QtPrivate::detail::getOffset(Offset));
1373 }
1374
1375public:
1376 using value_type = T;
1378
1380
1382 {
1383 qGetBindingStorage(owner())->registerDependency(this);
1384 return (owner()->*Getter)();
1385 }
1386
1388 operator->() const
1389 {
1390 if constexpr (QTypeTraits::is_dereferenceable_v<T>)
1391 return value();
1392 else
1393 return;
1394 }
1395
1397 {
1398 return value();
1399 }
1400
1402 {
1403 return value();
1404 }
1405
1406 constexpr bool hasBinding() const { return false; }
1407
1408 template<typename Functor>
1410 {
1411 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
1412 return QPropertyChangeHandler<Functor>(*this, std::move(f));
1413 }
1414
1415 template<typename Functor>
1417 {
1418 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
1419 f();
1420 return onValueChanged(std::move(f));
1421 }
1422
1423 template<typename Functor>
1425 {
1426 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
1427 return QPropertyNotifier(*this, std::move(f));
1428 }
1429
1431 {
1432 auto *storage = const_cast<QBindingStorage *>(qGetBindingStorage(owner()));
1433 return *storage->bindingData(const_cast<QObjectComputedProperty *>(this), true);
1434 }
1435
1436 void notify() {
1437 // computed property can't store a binding, so there's nothing to mark
1438 auto *storage = const_cast<QBindingStorage *>(qGetBindingStorage(owner()));
1439 auto bd = storage->bindingData(const_cast<QObjectComputedProperty *>(this), false);
1440 if (bd)
1442 }
1443};
1444
1445#define Q_OBJECT_COMPUTED_PROPERTY(Class, Type, name, ...)
1446 static constexpr size_t _qt_property_##name##_offset() {
1447 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1448 return offsetof(Class, name);
1449 QT_WARNING_POP
1450 }
1451 QObjectComputedProperty<Class, Type, Class::_qt_property_##name##_offset, __VA_ARGS__> name;
1452
1453#undef QT_SOURCE_LOCATION_NAMESPACE
1454
1455QT_END_NAMESPACE
1456
1457#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:907
QPropertyBinding< T > binding() const
Returns the currently set binding of the underlying property.
Definition qproperty.h:911
T value() const
Returns the underlying property's current value.
Definition qproperty.h:949
void setValue(const T &value)
Sets the underlying property's value to value.
Definition qproperty.h:959
friend class QPropertyAlias
Definition qproperty.h:887
QBindable(QObject *obj, const QMetaProperty &property)
Definition qproperty.h:901
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:938
QBindable(const QUntypedBindable &b)
Definition qproperty.h:893
QPropertyBinding< T > setBinding(const QPropertyBinding< T > &binding)
Sets the underlying property's binding to binding.
Definition qproperty.h:922
QBindable(QObject *obj, const char *property)
Definition qproperty.h:904
QPropertyBinding< T > takeBinding()
Removes the currently set binding of the underlying property and returns it.
Definition qproperty.h:916
\inmodule QtCore
\inmodule QtCore
Definition qproperty.h:1097
QObjectBindableProperty(const T &initialValue)
Constructs a property with the provided initialValue.
Definition qproperty.h:1128
QObjectBindableProperty()=default
typename QPropertyData< T >::rvalue_ref rvalue_ref
Definition qproperty.h:1124
typename QPropertyData< T >::value_type value_type
Definition qproperty.h:1122
QObjectBindableProperty(T &&initialValue)
Move-Constructs a property with the provided initialValue.
Definition qproperty.h:1129
typename QPropertyData< T >::arrow_operator_result arrow_operator_result
Definition qproperty.h:1125
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:1135
QObjectBindableProperty(const QPropertyBinding< T > &binding)
Definition qproperty.h:1130
typename QPropertyData< T >::parameter_type parameter_type
Definition qproperty.h:1123
\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:1363
QObjectComputedProperty()=default
parameter_type value() const
Definition qproperty.h:1381
\inmodule QtCore
Definition qproperty.h:133
QPropertyBinding(const QUntypedPropertyBinding &binding)
Definition qproperty.h:215
QPropertyBinding()=default
QPropertyBinding(Functor &&f, const QPropertyBindingSourceLocation &location)
Definition qproperty.h:209
\inmodule QtCore
Definition qproperty.h:302
\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:329
QUntypedPropertyData * aliasData
Definition qproperty.h:264
void(*)(QPropertyObserver *, QUntypedPropertyData *) ChangeHandler
Definition qproperty.h:246
ChangeHandler changeHandler
Definition qproperty.h:263
QPropertyBindingPrivate * binding
Definition qproperty.h:262
\inmodule QtCore
Definition qproperty.h:361
typename QPropertyData< T >::arrow_operator_result arrow_operator_result
Definition qproperty.h:387
QProperty(rvalue_ref initialValue)
Definition qproperty.h:391
void setValue(rvalue_ref newValue)
Definition qproperty.h:456
typename QPropertyData< T >::value_type value_type
Definition qproperty.h:384
QPropertyChangeHandler< Functor > subscribe(Functor f)
Definition qproperty.h:532
QPropertyBinding< T > takeBinding()
Disassociates the binding expression from this property and returns it.
Definition qproperty.h:519
bool hasBinding() const
Definition qproperty.h:512
bool setBinding(const QUntypedPropertyBinding &newBinding)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qproperty.h:491
friend void operator!=(const QProperty &, const QProperty< U > &) QPROPERTY_DECL_DELETED_EQ_OP
QPropertyNotifier addNotifier(Functor f)
Definition qproperty.h:540
typename QPropertyData< T >::rvalue_ref rvalue_ref
Definition qproperty.h:386
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:525
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:501
void setValue(parameter_type newValue)
Assigns newValue to this property and removes the property's associated binding, if present.
Definition qproperty.h:465
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:392
parameter_type value() const
Returns the value of the property.
Definition qproperty.h:428
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:486
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:397
const QtPrivate::QPropertyBindingData & bindingData() const
Definition qproperty.h:546
typename QPropertyData< T >::parameter_type parameter_type
Definition qproperty.h:385
QProperty< T > & operator=(rvalue_ref newValue)
Definition qproperty.h:474
arrow_operator_result operator->() const
Definition qproperty.h:434
QProperty< T > & operator=(parameter_type newValue)
Assigns newValue to this property and returns a reference to this QProperty.
Definition qproperty.h:480
QPropertyBinding< T > binding() const
Returns the binding expression that is associated with this property.
Definition qproperty.h:514
parameter_type operator*() const
Definition qproperty.h:446
operator parameter_type() const
Definition qproperty.h:451
~QProperty()=default
Destroys the property.
QProperty(parameter_type initialValue)
Definition qproperty.h:390
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:751
QUntypedPropertyBinding binding() const
Returns the underlying property's binding if there is any, or a default constructed QUntypedPropertyB...
Definition qproperty.h:831
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:775
bool hasBinding() const
Returns true if the underlying property has a binding.
Definition qproperty.h:861
constexpr QUntypedBindable()=default
Default-constructs a QUntypedBindable.
QMetaType metaType() const
Definition qproperty.h:866
const QtPrivate::QBindableInterface * iface
Definition qproperty.h:755
QPropertyChangeHandler< Functor > onValueChanged(Functor f) const
Installs f as a change handler.
Definition qproperty.h:809
QUntypedPropertyBinding takeBinding()
Removes the currently set binding from the property and returns it.
Definition qproperty.h:780
QPropertyNotifier addNotifier(Functor f)
Installs f as a change handler.
Definition qproperty.h:824
QUntypedPropertyData * data
Definition qproperty.h:754
bool isBindable() const
Definition qproperty.h:772
bool isValid() const
Returns true if the QUntypedBindable is valid.
Definition qproperty.h:771
bool setBinding(const QUntypedPropertyBinding &binding)
Sets the underlying property's binding to binding.
Definition qproperty.h:842
bool isReadOnly() const
Definition qproperty.h:773
QUntypedBindable(Property *p)
Constructs a QUntypedBindable from the property property.
Definition qproperty.h:766
QPropertyChangeHandler< Functor > subscribe(Functor f) const
Behaves like a call to f followed by onValueChanged(f),.
Definition qproperty.h:817
constexpr QUntypedBindable(QUntypedPropertyData *d, const QtPrivate::QBindableInterface *i)
Definition qproperty.h:756
void observe(QPropertyObserver *observer) const
Definition qproperty.h:797
\inmodule QtCore
Definition qproperty.h:160
static constexpr QBindableInterface iface
Definition qproperty.h:615
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:707
constexpr QBindableInterface iface
Definition qproperty.h:726
bool bindingWrapper(QMetaType type, QUntypedPropertyData *d, QtPrivate::QPropertyBindingFunction binding)
Definition qproperty.h:696
QUntypedPropertyBinding makeBinding(const QUntypedPropertyData *d, const QPropertyBindingSourceLocation &location)
Definition qproperty.h:713
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:222
Q_CORE_EXPORT void beginPropertyUpdateGroup()
QPropertyBinding< PropertyType > makePropertyBinding(const QProperty< PropertyType > &otherProperty, const QPropertyBindingSourceLocation &location=QT_PROPERTY_DEFAULT_BINDING_LOCATION)
Definition qproperty.h:576
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:456
QBindingStorage * qGetBindingStorage(QObjectPrivate::ExtraData *ed)
Definition qobject_p.h:464
const QBindingStorage * qGetBindingStorage(const QObjectPrivate *o)
Definition qobject_p.h:452
#define QPROPERTY_DECL_DELETED_EQ_OP
Definition qproperty.h:419
#define Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(...)
Definition qproperty.h:1356
#define QT_PROPERTY_DEFAULT_BINDING_LOCATION
Definition qproperty.h:48
#define Q_OBJECT_COMPUTED_PROPERTY(Class, Type, name, ...)
Definition qproperty.h:1445
#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:590
void(*)(const QUntypedPropertyData *d, QPropertyObserver *observer) SetObserver
Definition qproperty.h:595
void(*)(QUntypedPropertyData *d, const void *value) Setter
Definition qproperty.h:591
static constexpr quintptr MetaTypeAccessorFlag
Definition qproperty.h:605