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
188private:
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().isSameType<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>
525 [[nodiscard]]
527 {
528 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
529 return QPropertyChangeHandler<Functor>(*this, std::move(f));
530 }
531
532 template<typename Functor>
533 [[nodiscard]]
535 {
536 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
537 f();
538 return onValueChanged(std::move(f));
539 }
540
541 template<typename Functor>
542 [[nodiscard]]
544 {
545 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
546 return QPropertyNotifier(*this, std::move(f));
547 }
548
549 const QtPrivate::QPropertyBindingData &bindingData() const { return d; }
550private:
551 template <typename Ty = T, std::enable_if_t<QTypeTraits::has_operator_equal_v<Ty>>* = nullptr>
552 friend bool comparesEqual(const QProperty &lhs, const QProperty &rhs)
553 {
554 return lhs.value() == rhs.value();
555 }
556
557 template <typename Ty = T, std::enable_if_t<QTypeTraits::has_operator_equal_v<Ty>>* = nullptr>
558 friend bool comparesEqual(const QProperty &lhs, const T &rhs)
559 {
560 return lhs.value() == rhs;
561 }
562
563 template <typename U, std::enable_if_t<has_operator_equal_to_v<U>>* = nullptr>
564 friend bool comparesEqual(const QProperty &lhs, const U &rhs)
565 {
566 return lhs.value() == rhs;
567 }
568
569 void notify()
570 {
571 d.notifyObservers(this);
572 }
573
575};
576
577namespace Qt {
578 template <typename PropertyType>
579 QPropertyBinding<PropertyType> makePropertyBinding(const QProperty<PropertyType> &otherProperty,
580 const QPropertyBindingSourceLocation &location =
582 {
583 return Qt::makePropertyBinding([&otherProperty]() -> PropertyType { return otherProperty; }, location);
584 }
585}
586
587
588namespace QtPrivate
589{
590
592{
593 using Getter = void (*)(const QUntypedPropertyData *d, void *value);
594 using Setter = void (*)(QUntypedPropertyData *d, const void *value);
598 using SetObserver = void (*)(const QUntypedPropertyData *d, QPropertyObserver *observer);
599 using GetMetaType = QMetaType (*)();
607
608 static constexpr quintptr MetaTypeAccessorFlag = 0x1;
609};
610
611template<typename Property, typename = void>
613{
614 using T = typename Property::value_type;
615public:
616 // interface for computed properties. Those do not have a binding()/setBinding() method, but one can
617 // install observers on them.
618 static constexpr QBindableInterface iface = {
619 [](const QUntypedPropertyData *d, void *value) -> void
620 { *static_cast<T*>(value) = static_cast<const Property *>(d)->value(); },
621 nullptr,
622 nullptr,
623 nullptr,
625 { return Qt::makePropertyBinding([d]() -> T { return static_cast<const Property *>(d)->value(); }, location); },
627 { observer->setSource(static_cast<const Property *>(d)->bindingData()); },
628 []() { return QMetaType::fromType<T>(); }
629 };
630};
631
632template<typename Property>
634{
635 using T = typename Property::value_type;
636public:
637 // A bindable created from a const property results in a read-only interface, too.
638 static constexpr QBindableInterface iface = {
639
640 [](const QUntypedPropertyData *d, void *value) -> void
641 { *static_cast<T*>(value) = static_cast<const Property *>(d)->value(); },
642 /*setter=*/nullptr,
644 { return static_cast<const Property *>(d)->binding(); },
645 /*setBinding=*/nullptr,
647 { return Qt::makePropertyBinding([d]() -> T { return static_cast<const Property *>(d)->value(); }, location); },
649 { observer->setSource(static_cast<const Property *>(d)->bindingData()); },
650 []() { return QMetaType::fromType<T>(); }
651 };
652};
653
654template<typename Property>
656{
657 using T = typename Property::value_type;
658public:
659 static constexpr QBindableInterface iface = {
660 [](const QUntypedPropertyData *d, void *value) -> void
661 { *static_cast<T*>(value) = static_cast<const Property *>(d)->value(); },
662 [](QUntypedPropertyData *d, const void *value) -> void
663 { static_cast<Property *>(d)->setValue(*static_cast<const T*>(value)); },
665 { return static_cast<const Property *>(d)->binding(); },
667 { return static_cast<Property *>(d)->setBinding(static_cast<const QPropertyBinding<T> &>(binding)); },
669 { return Qt::makePropertyBinding([d]() -> T { return static_cast<const Property *>(d)->value(); }, location); },
671 { observer->setSource(static_cast<const Property *>(d)->bindingData()); },
672 []() { return QMetaType::fromType<T>(); }
673 };
674};
675
676}
677
678namespace QtPrivate {
679// used in Q(Untyped)Bindable to print warnings about various binding errors
680namespace BindableWarnings {
682Q_CORE_EXPORT void printUnsuitableBindableWarning(QAnyStringView prefix, Reason reason);
683Q_CORE_EXPORT void printMetaTypeMismatch(QMetaType actual, QMetaType expected);
684}
685
687Q_CORE_EXPORT void getter(const QUntypedPropertyData *d, void *value);
688Q_CORE_EXPORT void setter(QUntypedPropertyData *d, const void *value);
689Q_CORE_EXPORT QUntypedPropertyBinding getBinding(const QUntypedPropertyData *d);
690Q_CORE_EXPORT bool bindingWrapper(QMetaType type, QUntypedPropertyData *d,
691 QtPrivate::QPropertyBindingFunction binding,
692 QUntypedPropertyData *temp, void *value);
693Q_CORE_EXPORT QUntypedPropertyBinding setBinding(QUntypedPropertyData *d,
696Q_CORE_EXPORT void setObserver(const QUntypedPropertyData *d, QPropertyObserver *observer);
697
698template<typename T>
699bool bindingWrapper(QMetaType type, QUntypedPropertyData *d,
700 QtPrivate::QPropertyBindingFunction binding)
701{
702 struct Data : QPropertyData<T>
703 {
704 void *data() { return &this->val; }
705 } temp;
706 return bindingWrapper(type, d, binding, &temp, temp.data());
707}
708
709template<typename T>
710QUntypedPropertyBinding setBinding(QUntypedPropertyData *d, const QUntypedPropertyBinding &binding)
711{
712 return setBinding(d, binding, &bindingWrapper<T>);
713}
714
715template<typename T>
716QUntypedPropertyBinding makeBinding(const QUntypedPropertyData *d,
717 const QPropertyBindingSourceLocation &location)
718{
719 return Qt::makePropertyBinding(
720 [d]() -> T {
721 T r;
722 getter(d, &r);
723 return r;
724 },
725 location);
726}
727
728template<class T>
729inline constexpr QBindableInterface iface = {
730#ifdef QT_NO_DATA_RELOCATION
731 // On windows the address of a dllimported function can't be relocated here.
732 // MSVC automatically generates a trampoline, but clang won't, so do it explicitly.
733 [](const QUntypedPropertyData *d, void *value) { getter(d, value); },
734 [](QUntypedPropertyData *d, const void *value) { setter(d, value); },
735 [](const QUntypedPropertyData *d) -> QUntypedPropertyBinding { return getBinding(d); },
736 &setBinding<T>,
737 &makeBinding<T>,
740#else
741 &getter,
742 &setter,
743 &getBinding,
744 &setBinding<T>,
745 &makeBinding<T>,
748#endif
749};
750}
751}
752
754{
755 friend struct QUntypedBindablePrivate; // allows access to internal data
756protected:
759 constexpr QUntypedBindable(QUntypedPropertyData *d, const QtPrivate::QBindableInterface *i)
760 : data(d), iface(i)
761 {}
762
765
766public:
767 constexpr QUntypedBindable() = default;
768 template<typename Property>
769 QUntypedBindable(Property *p)
770 : data(const_cast<std::remove_cv_t<Property> *>(p)),
772 { Q_ASSERT(data && iface); }
773
774 bool isValid() const { return data != nullptr; }
775 bool isBindable() const { return iface && iface->getBinding; }
776 bool isReadOnly() const { return !(iface && iface->setBinding && iface->setObserver); }
777
778 QUntypedPropertyBinding makeBinding(const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION) const
779 {
780 return iface ? iface->makeBinding(data, location) : QUntypedPropertyBinding();
781 }
782
784 {
785 if (!iface)
786 return QUntypedPropertyBinding {};
787 // We do not have a dedicated takeBinding function pointer in the interface
788 // therefore we synthesize takeBinding by retrieving the binding with binding
789 // and calling setBinding with a default constructed QUntypedPropertyBinding
790 // afterwards.
791 if (!(iface->getBinding && iface->setBinding))
792 return QUntypedPropertyBinding {};
793 return [&] {
794 QUntypedPropertyBinding binding = iface->getBinding(data);
795 iface->setBinding(data, QUntypedPropertyBinding{});
796 return binding;
797 }();
798 }
799
800 void observe(QPropertyObserver *observer) const
801 {
802 if (iface)
803 iface->setObserver(data, observer);
804#ifndef QT_NO_DEBUG
805 else
808#endif
809 }
810
811 template<typename Functor>
812 [[nodiscard]]
813 QPropertyChangeHandler<Functor> onValueChanged(Functor f) const
814 {
815 QPropertyChangeHandler<Functor> handler(std::move(f));
816 observe(&handler);
817 return handler;
818 }
819
820 template<typename Functor>
821 [[nodiscard]]
822 QPropertyChangeHandler<Functor> subscribe(Functor f) const
823 {
824 f();
825 return onValueChanged(std::move(f));
826 }
827
828 template<typename Functor>
829 [[nodiscard]]
831 {
832 QPropertyNotifier handler(std::move(f));
833 observe(&handler);
834 return handler;
835 }
836
838 {
839 if (!isBindable()) {
840#ifndef QT_NO_DEBUG
843#endif
844 return QUntypedPropertyBinding();
845 }
846 return iface->getBinding(data);
847 }
848 bool setBinding(const QUntypedPropertyBinding &binding)
849 {
850 if (isReadOnly()) {
851#ifndef QT_NO_DEBUG
854 QtPrivate::BindableWarnings::printUnsuitableBindableWarning("setBinding: Could not set binding via bindable interface.", errorType);
855#endif
856 return false;
857 }
858 if (!binding.isNull() && binding.valueMetaType() != metaType()) {
859#ifndef QT_NO_DEBUG
860 QtPrivate::BindableWarnings::printMetaTypeMismatch(metaType(), binding.valueMetaType());
861#endif
862 return false;
863 }
864 iface->setBinding(data, binding);
865 return true;
866 }
867 bool hasBinding() const
868 {
869 return !binding().isNull();
870 }
871
873 {
874 if (!(iface && data))
875 return QMetaType();
876 if (iface->metaType)
877 return iface->metaType();
878 // ### Qt 7: Change the metatype function to take data as its argument
879 // special casing for QML's proxy bindable: allow multiplexing in the getter
880 // function to retrieve the metatype from data
881 Q_ASSERT(iface->getter);
882 QMetaType result;
883 iface->getter(data, reinterpret_cast<void *>(quintptr(&result) | QtPrivate::QBindableInterface::MetaTypeAccessorFlag));
884 return result;
885 }
886
887};
888
889template<typename T>
890class QBindable : public QUntypedBindable
891{
892 template<typename U>
893 friend class QPropertyAlias;
894 constexpr QBindable(QUntypedPropertyData *d, const QtPrivate::QBindableInterface *i)
895 : QUntypedBindable(d, i)
896 {}
897public:
898 using QUntypedBindable::QUntypedBindable;
900 {
901 if (iface && metaType() != QMetaType::fromType<T>()) {
902 data = nullptr;
903 iface = nullptr;
904 }
905 }
906
907 explicit QBindable(QObject *obj, const QMetaProperty &property)
908 : QUntypedBindable(obj, property, &QtPrivate::PropertyAdaptorSlotObjectHelpers::iface<T>) {}
909
910 explicit QBindable(QObject *obj, const char *property)
911 : QUntypedBindable(obj, property, &QtPrivate::PropertyAdaptorSlotObjectHelpers::iface<T>) {}
912
913 QPropertyBinding<T> makeBinding(const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION) const
914 {
915 return static_cast<QPropertyBinding<T> &&>(QUntypedBindable::makeBinding(location));
916 }
918 {
919 return static_cast<QPropertyBinding<T> &&>(QUntypedBindable::binding());
920 }
921
923 {
924 return static_cast<QPropertyBinding<T> &&>(QUntypedBindable::takeBinding());
925 }
926
927 using QUntypedBindable::setBinding;
929 {
930 Q_ASSERT(!iface || binding.isNull() || binding.valueMetaType() == metaType());
931
932 if (iface && iface->setBinding)
933 return static_cast<QPropertyBinding<T> &&>(iface->setBinding(data, binding));
934#ifndef QT_NO_DEBUG
935 if (!iface)
937 else
939#endif
940 return QPropertyBinding<T>();
941 }
942#ifndef Q_QDOC
943 template <typename Functor>
945 const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION,
946 std::enable_if_t<std::is_invocable_v<Functor>> * = nullptr)
947 {
948 return setBinding(Qt::makePropertyBinding(std::forward<Functor>(f), location));
949 }
950#else
951 template <typename Functor>
952 QPropertyBinding<T> setBinding(Functor f);
953#endif
954
955 T value() const
956 {
957 if (iface) {
958 T result;
959 iface->getter(data, &result);
960 return result;
961 }
962 return T{};
963 }
964
965 void setValue(const T &value)
966 {
967 if (iface && iface->setter)
968 iface->setter(data, &value);
969 }
970};
971
972#if QT_DEPRECATED_SINCE(6, 6)
973template<typename T>
974class QT_DEPRECATED_VERSION_X_6_6("Class was only meant for internal use, use a QProperty and add a binding to the target")
975QPropertyAlias : public QPropertyObserver
976{
977 Q_DISABLE_COPY_MOVE(QPropertyAlias)
978 const QtPrivate::QBindableInterface *iface = nullptr;
979
980public:
981 QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
982 QPropertyAlias(QProperty<T> *property)
983 : QPropertyObserver(property),
984 iface(&QtPrivate::QBindableInterfaceForProperty<QProperty<T>>::iface)
985 {
986 if (iface)
987 iface->setObserver(aliasedProperty(), this);
988 }
989
990 template <typename Property, QtPrivate::IsUntypedPropertyData<Property> = true>
991 QPropertyAlias(Property *property)
992 : QPropertyObserver(property),
993 iface(&QtPrivate::QBindableInterfaceForProperty<Property>::iface)
994 {
995 if (iface)
996 iface->setObserver(aliasedProperty(), this);
997 }
998
999 QPropertyAlias(QPropertyAlias<T> *alias)
1000 : QPropertyObserver(alias->aliasedProperty()),
1001 iface(alias->iface)
1002 {
1003 if (iface)
1004 iface->setObserver(aliasedProperty(), this);
1005 }
1006
1007 QPropertyAlias(const QBindable<T> &property)
1008 : QPropertyObserver(property.data),
1009 iface(property.iface)
1010 {
1011 if (iface)
1012 iface->setObserver(aliasedProperty(), this);
1013 }
1014
1015 T value() const
1016 {
1017 T t = T();
1018 if (auto *p = aliasedProperty())
1019 iface->getter(p, &t);
1020 return t;
1021 }
1022
1023 operator T() const { return value(); }
1024
1025 void setValue(const T &newValue)
1026 {
1027 if (auto *p = aliasedProperty())
1028 iface->setter(p, &newValue);
1029 }
1030
1031 QPropertyAlias<T> &operator=(const T &newValue)
1032 {
1033 setValue(newValue);
1034 return *this;
1035 }
1036
1037 QPropertyBinding<T> setBinding(const QPropertyBinding<T> &newBinding)
1038 {
1039 return QBindable<T>(aliasedProperty(), iface).setBinding(newBinding);
1040 }
1041
1042 bool setBinding(const QUntypedPropertyBinding &newBinding)
1043 {
1044 return QBindable<T>(aliasedProperty(), iface).setBinding(newBinding);
1045 }
1046
1047#ifndef Q_QDOC
1048 template <typename Functor>
1049 QPropertyBinding<T> setBinding(Functor &&f,
1050 const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION,
1051 std::enable_if_t<std::is_invocable_v<Functor>> * = nullptr)
1052 {
1053 return setBinding(Qt::makePropertyBinding(std::forward<Functor>(f), location));
1054 }
1055#else
1056 template <typename Functor>
1057 QPropertyBinding<T> setBinding(Functor f);
1058#endif
1059
1060 bool hasBinding() const
1061 {
1062 return QBindable<T>(aliasedProperty(), iface).hasBinding();
1063 }
1064
1065 QPropertyBinding<T> binding() const
1066 {
1067 return QBindable<T>(aliasedProperty(), iface).binding();
1068 }
1069
1070 QPropertyBinding<T> takeBinding()
1071 {
1072 return QBindable<T>(aliasedProperty(), iface).takeBinding();
1073 }
1074
1075 template<typename Functor>
1076 [[nodiscard]]
1077 QPropertyChangeHandler<Functor> onValueChanged(Functor f)
1078 {
1079 return QBindable<T>(aliasedProperty(), iface).onValueChanged(std::move(f));
1080 }
1081
1082 template<typename Functor>
1083 [[nodiscard]]
1084 QPropertyChangeHandler<Functor> subscribe(Functor f)
1085 {
1086 return QBindable<T>(aliasedProperty(), iface).subscribe(std::move(f));
1087 }
1088
1089 template<typename Functor>
1090 [[nodiscard]]
1091 QPropertyNotifier addNotifier(Functor f)
1092 {
1093 return QBindable<T>(aliasedProperty(), iface).addNotifier(std::move(f));
1094 }
1095
1096 bool isValid() const
1097 {
1098 return aliasedProperty() != nullptr;
1099 }
1100 QT_WARNING_POP
1101};
1102#endif // QT_DEPRECATED_SINCE(6, 6)
1103
1104template<typename Class, typename T, auto Offset, auto Signal = nullptr>
1106{
1108 static bool constexpr HasSignal = !std::is_same_v<decltype(Signal), std::nullptr_t>;
1109 using SignalTakesValue = std::is_invocable<decltype(Signal), Class, T>;
1110 Class *owner()
1111 {
1112 char *that = reinterpret_cast<char *>(this);
1113 return reinterpret_cast<Class *>(that - QtPrivate::detail::getOffset(Offset));
1114 }
1115 const Class *owner() const
1116 {
1117 char *that = const_cast<char *>(reinterpret_cast<const char *>(this));
1118 return reinterpret_cast<Class *>(that - QtPrivate::detail::getOffset(Offset));
1119 }
1120 static void signalCallBack(QUntypedPropertyData *o)
1121 {
1122 QObjectBindableProperty *that = static_cast<QObjectBindableProperty *>(o);
1123 if constexpr (HasSignal) {
1124 if constexpr (SignalTakesValue::value)
1125 (that->owner()->*Signal)(that->valueBypassingBindings());
1126 else
1127 (that->owner()->*Signal)();
1128 }
1129 }
1130public:
1135
1137 explicit QObjectBindableProperty(const T &initialValue) : QPropertyData<T>(initialValue) {}
1138 explicit QObjectBindableProperty(T &&initialValue) : QPropertyData<T>(std::move(initialValue)) {}
1139 explicit QObjectBindableProperty(const QPropertyBinding<T> &binding)
1141 { setBinding(binding); }
1142#ifndef Q_QDOC
1143 template <typename Functor>
1144 explicit QObjectBindableProperty(Functor &&f, const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION,
1145 typename std::enable_if_t<std::is_invocable_r_v<T, Functor&>> * = nullptr)
1146 : QObjectBindableProperty(QPropertyBinding<T>(std::forward<Functor>(f), location))
1147 {}
1148#else
1149 template <typename Functor>
1150 explicit QObjectBindableProperty(Functor &&f);
1151#endif
1152
1153 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>)
1154 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>)
1155 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>)
1156
1158 {
1160 return this->val;
1161 }
1162
1164 {
1165 if constexpr (QTypeTraits::is_dereferenceable_v<T>) {
1166 return value();
1167 } else if constexpr (std::is_pointer_v<T>) {
1168 value();
1169 return this->val;
1170 } else {
1171 return;
1172 }
1173 }
1174
1176 {
1177 return value();
1178 }
1179
1181 {
1182 return value();
1183 }
1184
1186 {
1187 auto *bd = qGetBindingStorage(owner())->bindingData(this);
1188 if (bd)
1189 bd->removeBinding();
1190 if (this->val == t)
1191 return;
1192 this->val = t;
1193 notify(bd);
1194 }
1195
1196 void notify() {
1197 auto *bd = qGetBindingStorage(owner())->bindingData(this);
1198 notify(bd);
1199 }
1200
1202 {
1203 auto *bd = qGetBindingStorage(owner())->bindingData(this);
1204 if (bd)
1205 bd->removeBinding();
1206 if (this->val == t)
1207 return;
1208 this->val = std::move(t);
1209 notify(bd);
1210 }
1211
1213 {
1215 return *this;
1216 }
1217
1219 {
1221 return *this;
1222 }
1223
1230
1232 {
1234 return false;
1235 setBinding(static_cast<const QPropertyBinding<T> &>(newBinding));
1236 return true;
1237 }
1238
1239#ifndef Q_QDOC
1240 template <typename Functor>
1247#else
1248 template <typename Functor>
1250#endif
1251
1252 bool hasBinding() const
1253 {
1254 auto *bd = qGetBindingStorage(owner())->bindingData(this);
1255 return bd && bd->binding() != nullptr;
1256 }
1257
1259 {
1260 auto *bd = qGetBindingStorage(owner())->bindingData(this);
1261 return static_cast<QPropertyBinding<T> &&>(QUntypedPropertyBinding(bd ? bd->binding() : nullptr));
1262 }
1263
1265 {
1266 return setBinding(QPropertyBinding<T>());
1267 }
1268
1269 template<typename Functor>
1270 [[nodiscard]]
1272 {
1273 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
1274 return QPropertyChangeHandler<Functor>(*this, std::move(f));
1275 }
1276
1277 template<typename Functor>
1278 [[nodiscard]]
1280 {
1281 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
1282 f();
1283 return onValueChanged(std::move(f));
1284 }
1285
1286 template<typename Functor>
1287 [[nodiscard]]
1289 {
1290 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
1291 return QPropertyNotifier(*this, std::move(f));
1292 }
1293
1295 {
1296 auto *storage = const_cast<QBindingStorage *>(qGetBindingStorage(owner()));
1297 return *storage->bindingData(const_cast<ThisType *>(this), true);
1298 }
1299private:
1300 template <typename Ty = T, std::enable_if_t<QTypeTraits::has_operator_equal_v<Ty>>* = nullptr>
1302 {
1303 return lhs.value() == rhs.value();
1304 }
1305
1306 template <typename Ty = T, std::enable_if_t<QTypeTraits::has_operator_equal_v<Ty>>* = nullptr>
1307 friend bool comparesEqual(const QObjectBindableProperty &lhs, const T &rhs)
1308 {
1309 return lhs.value() == rhs;
1310 }
1311
1313 {
1314 if (binding)
1316 if constexpr (HasSignal) {
1317 if constexpr (SignalTakesValue::value)
1318 (owner()->*Signal)(this->valueBypassingBindings());
1319 else
1320 (owner()->*Signal)();
1321 }
1322 }
1323};
1324
1325#define QT_OBJECT_BINDABLE_PROPERTY_3(Class, Type, name)
1326 static constexpr size_t _qt_property_##name##_offset() {
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, nullptr> name;
1332
1333#define QT_OBJECT_BINDABLE_PROPERTY_4(Class, Type, name, Signal)
1334 static constexpr size_t _qt_property_##name##_offset() {
1335 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1336 return offsetof(Class, name);
1337 QT_WARNING_POP
1338 }
1339 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, Signal> name;
1340
1341#define Q_OBJECT_BINDABLE_PROPERTY(...)
1342 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1343 QT_OVERLOADED_MACRO(QT_OBJECT_BINDABLE_PROPERTY, __VA_ARGS__)
1344 QT_WARNING_POP
1345
1346#define QT_OBJECT_BINDABLE_PROPERTY_WITH_ARGS_4(Class, Type, name, value)
1347 static constexpr size_t _qt_property_##name##_offset()
1348 {
1349 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1350 return offsetof(Class, name);
1351 QT_WARNING_POP
1352 }
1353 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, nullptr> name =
1354 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, nullptr>(
1355 value);
1356
1357#define QT_OBJECT_BINDABLE_PROPERTY_WITH_ARGS_5(Class, Type, name, value, Signal)
1358 static constexpr size_t _qt_property_##name##_offset()
1359 {
1360 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1361 return offsetof(Class, name);
1362 QT_WARNING_POP
1363 }
1364 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, Signal> name =
1365 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, Signal>(
1366 value);
1367
1368#define Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(...)
1369 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1370 QT_OVERLOADED_MACRO(QT_OBJECT_BINDABLE_PROPERTY_WITH_ARGS, __VA_ARGS__)
1371 QT_WARNING_POP
1372
1373template<typename Class, typename T, auto Offset, auto Getter>
1375{
1376 Class *owner()
1377 {
1378 char *that = reinterpret_cast<char *>(this);
1379 return reinterpret_cast<Class *>(that - QtPrivate::detail::getOffset(Offset));
1380 }
1381 const Class *owner() const
1382 {
1383 char *that = const_cast<char *>(reinterpret_cast<const char *>(this));
1384 return reinterpret_cast<Class *>(that - QtPrivate::detail::getOffset(Offset));
1385 }
1386
1387public:
1388 using value_type = T;
1390
1392
1394 {
1395 qGetBindingStorage(owner())->registerDependency(this);
1396 return (owner()->*Getter)();
1397 }
1398
1400 operator->() const
1401 {
1402 if constexpr (QTypeTraits::is_dereferenceable_v<T>)
1403 return value();
1404 else
1405 return;
1406 }
1407
1409 {
1410 return value();
1411 }
1412
1414 {
1415 return value();
1416 }
1417
1418 constexpr bool hasBinding() const { return false; }
1419
1420 template<typename Functor>
1421 [[nodiscard]]
1423 {
1424 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
1425 return QPropertyChangeHandler<Functor>(*this, std::move(f));
1426 }
1427
1428 template<typename Functor>
1429 [[nodiscard]]
1431 {
1432 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
1433 f();
1434 return onValueChanged(std::move(f));
1435 }
1436
1437 template<typename Functor>
1438 [[nodiscard]]
1440 {
1441 static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
1442 return QPropertyNotifier(*this, std::move(f));
1443 }
1444
1446 {
1447 auto *storage = const_cast<QBindingStorage *>(qGetBindingStorage(owner()));
1448 return *storage->bindingData(const_cast<QObjectComputedProperty *>(this), true);
1449 }
1450
1451 void notify() {
1452 // computed property can't store a binding, so there's nothing to mark
1453 auto *storage = const_cast<QBindingStorage *>(qGetBindingStorage(owner()));
1454 auto bd = storage->bindingData(const_cast<QObjectComputedProperty *>(this), false);
1455 if (bd)
1457 }
1458};
1459
1460#define Q_OBJECT_COMPUTED_PROPERTY(Class, Type, name, ...)
1461 static constexpr size_t _qt_property_##name##_offset() {
1462 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF
1463 return offsetof(Class, name);
1464 QT_WARNING_POP
1465 }
1466 QObjectComputedProperty<Class, Type, Class::_qt_property_##name##_offset, __VA_ARGS__> name;
1467
1468#undef QT_SOURCE_LOCATION_NAMESPACE
1469
1470QT_END_NAMESPACE
1471
1472#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:913
QPropertyBinding< T > binding() const
Returns the currently set binding of the underlying property.
Definition qproperty.h:917
T value() const
Returns the underlying property's current value.
Definition qproperty.h:955
void setValue(const T &value)
Sets the underlying property's value to value.
Definition qproperty.h:965
friend class QPropertyAlias
Definition qproperty.h:893
QBindable(QObject *obj, const QMetaProperty &property)
Definition qproperty.h:907
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:944
QBindable(const QUntypedBindable &b)
Definition qproperty.h:899
QPropertyBinding< T > setBinding(const QPropertyBinding< T > &binding)
Sets the underlying property's binding to binding.
Definition qproperty.h:928
QBindable(QObject *obj, const char *property)
Definition qproperty.h:910
QPropertyBinding< T > takeBinding()
Removes the currently set binding of the underlying property and returns it.
Definition qproperty.h:922
\inmodule QtCore
\inmodule QtCore
Definition qproperty.h:1106
QObjectBindableProperty(const T &initialValue)
Constructs a property with the provided initialValue.
Definition qproperty.h:1137
QObjectBindableProperty()=default
typename QPropertyData< T >::rvalue_ref rvalue_ref
Definition qproperty.h:1133
typename QPropertyData< T >::value_type value_type
Definition qproperty.h:1131
QObjectBindableProperty(T &&initialValue)
Move-Constructs a property with the provided initialValue.
Definition qproperty.h:1138
typename QPropertyData< T >::arrow_operator_result arrow_operator_result
Definition qproperty.h:1134
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:1144
QObjectBindableProperty(const QPropertyBinding< T > &binding)
Definition qproperty.h:1139
typename QPropertyData< T >::parameter_type parameter_type
Definition qproperty.h:1132
\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:1375
QObjectComputedProperty()=default
parameter_type value() const
Definition qproperty.h:1393
\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:534
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:543
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:526
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:549
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:754
QUntypedPropertyBinding binding() const
Returns the underlying property's binding if there is any, or a default constructed QUntypedPropertyB...
Definition qproperty.h:837
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:778
bool hasBinding() const
Returns true if the underlying property has a binding.
Definition qproperty.h:867
constexpr QUntypedBindable()=default
Default-constructs a QUntypedBindable.
QMetaType metaType() const
Definition qproperty.h:872
const QtPrivate::QBindableInterface * iface
Definition qproperty.h:758
QPropertyChangeHandler< Functor > onValueChanged(Functor f) const
Installs f as a change handler.
Definition qproperty.h:813
QUntypedPropertyBinding takeBinding()
Removes the currently set binding from the property and returns it.
Definition qproperty.h:783
QPropertyNotifier addNotifier(Functor f)
Installs f as a change handler.
Definition qproperty.h:830
QUntypedPropertyData * data
Definition qproperty.h:757
bool isBindable() const
Definition qproperty.h:775
bool isValid() const
Returns true if the QUntypedBindable is valid.
Definition qproperty.h:774
bool setBinding(const QUntypedPropertyBinding &binding)
Sets the underlying property's binding to binding.
Definition qproperty.h:848
bool isReadOnly() const
Definition qproperty.h:776
QUntypedBindable(Property *p)
Constructs a QUntypedBindable from the property property.
Definition qproperty.h:769
QPropertyChangeHandler< Functor > subscribe(Functor f) const
Behaves like a call to f followed by onValueChanged(f),.
Definition qproperty.h:822
constexpr QUntypedBindable(QUntypedPropertyData *d, const QtPrivate::QBindableInterface *i)
Definition qproperty.h:759
void observe(QPropertyObserver *observer) const
Definition qproperty.h:800
\inmodule QtCore
Definition qproperty.h:160
static constexpr QBindableInterface iface
Definition qproperty.h:618
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:710
constexpr QBindableInterface iface
Definition qproperty.h:729
bool bindingWrapper(QMetaType type, QUntypedPropertyData *d, QtPrivate::QPropertyBindingFunction binding)
Definition qproperty.h:699
QUntypedPropertyBinding makeBinding(const QUntypedPropertyData *d, const QPropertyBindingSourceLocation &location)
Definition qproperty.h:716
void setObserver(const QUntypedPropertyData *d, QPropertyObserver *observer)
void assertObjectType(QObjectPrivate *d)
Definition qobject_p.h:253
Q_CORE_EXPORT bool isAnyBindingEvaluating()
Q_CORE_EXPORT void restoreBindingStatus(BindingEvaluationState *status)
const QObject * getQObject(const QObjectPrivate *d)
Definition qobject_p.h:248
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:579
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:458
QBindingStorage * qGetBindingStorage(QObjectPrivate::ExtraData *ed)
Definition qobject_p.h:466
const QBindingStorage * qGetBindingStorage(const QObjectPrivate *o)
Definition qobject_p.h:454
#define QPROPERTY_DECL_DELETED_EQ_OP
Definition qproperty.h:419
#define Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(...)
Definition qproperty.h:1368
#define QT_PROPERTY_DEFAULT_BINDING_LOCATION
Definition qproperty.h:48
#define Q_OBJECT_COMPUTED_PROPERTY(Class, Type, name, ...)
Definition qproperty.h:1460
#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:593
void(*)(const QUntypedPropertyData *d, QPropertyObserver *observer) SetObserver
Definition qproperty.h:598
void(*)(QUntypedPropertyData *d, const void *value) Setter
Definition qproperty.h:594
static constexpr quintptr MetaTypeAccessorFlag
Definition qproperty.h:608