summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qobject.h
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2012-03-01 18:52:32 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-30 12:56:44 +0100
commited827acc27530a97b84685920615359010d74f48 (patch)
treef603df3e597531a5bb6a6a21d4a565ba8262d614 /src/corelib/kernel/qobject.h
parentbf6a345baa21818010242566bef4f2c25cb72437 (diff)
QSignalBlocker: (new) RAII class for QObject::blockSignals()
I don't think I ever worked on a project of non-trivial size that didn't at some point add a QSignalBlocker. This commit adds code, tests and documentation. Later commits will convert naked blockSignals() calls to use QSignalBlocker. The implementation is purely inline to avoid the heavy overhead of cross-dll function calls for this miniscule task. This should not be a problem because QSignalBlocker only uses public API and a pattern that we anyway need to keep working until Qt 6, at least, so even changing the implementation later will be no problem as the old implementation lurking in non-recompiled code will be acceptable, too. This implementation is an evolution from KDTools' KDSignalBlocker, with the following changes: - Implements unblock() and reblock() - Uses the return value of blockSignals() instead of a separate signalsBlocked() call. Change-Id: I1933dfd72a0f5190324be377cfca3c54cf3d6828 Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Diffstat (limited to 'src/corelib/kernel/qobject.h')
-rw-r--r--src/corelib/kernel/qobject.h46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index e2000afc82..f9239bf575 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -549,6 +549,52 @@ template <class T> inline const char * qobject_interface_iid()
Q_CORE_EXPORT QDebug operator<<(QDebug, const QObject *);
#endif
+class Q_CORE_EXPORT QSignalBlocker
+{
+public:
+ inline explicit QSignalBlocker(QObject *o);
+ inline explicit QSignalBlocker(QObject &o);
+ inline ~QSignalBlocker();
+
+ inline void reblock();
+ inline void unblock();
+private:
+ Q_DISABLE_COPY(QSignalBlocker)
+ QObject * const m_o;
+ bool m_blocked;
+ bool m_inhibited;
+};
+
+QSignalBlocker::QSignalBlocker(QObject *o)
+ : m_o(o),
+ m_blocked(o && o->blockSignals(true)),
+ m_inhibited(false)
+{}
+
+QSignalBlocker::QSignalBlocker(QObject &o)
+ : m_o(&o),
+ m_blocked(o.blockSignals(true)),
+ m_inhibited(false)
+{}
+
+QSignalBlocker::~QSignalBlocker()
+{
+ if (m_o && !m_inhibited)
+ m_o->blockSignals(m_blocked);
+}
+
+void QSignalBlocker::reblock()
+{
+ if (m_o) m_o->blockSignals(true);
+ m_inhibited = false;
+}
+
+void QSignalBlocker::unblock()
+{
+ if (m_o) m_o->blockSignals(m_blocked);
+ m_inhibited = true;
+}
+
namespace QtPrivate {
inline QObject & deref_for_methodcall(QObject &o) { return o; }
inline QObject & deref_for_methodcall(QObject *o) { return *o; }