Wrapper with signals for primitive types
Solved
General and Desktop
-
Hi,
I'd like to create a wrapper for primitive types, that would emit a signal when the value is changed and have a slot to change the value.The obvious way would be to use a template class:template<typename Type> class QValueWrapper : public QObject { Q_OBJECT signals: void valueChanged(Type newValue); public: void setValue(const Type &newValue) { if(value_ != newValue) emit valueChanged(newValue); value_ = newValue; } private: Type value_; };
But Qt signals does not support template classes. So how would you do it? I'd like to avoid creating a wrapper for each value type, if possible
Thanks -
But Qt signals does not support template classes.
this is not strictly correct. It's MOC that can't cope with templates.
You have 3 alternatives that I can think of:
#include <wobjectdefs.h> #include <wobjectimpl.h> template<typename Type> class QValueWrapper : public QObject { W_OBJECT(QValueWrapper ) public: QValueWrapper(QObject* parent = nullptr) :QObject(parent){}; QValueWrapper(const Type & val,QObject* parent = nullptr) : QObject(parent), value_(val){} void valueChanged(Type newValue); W_SIGNAL(valueChanged, newValue) const Type & value() const {return value_;} void setValue(const Type &newValue) { if(value_ != newValue) emit valueChanged(newValue); value_ = newValue; } W_SLOT(setValue) private: Type value_; }; W_OBJECT_IMPL(QValueWrapper <Type>, template <typename Type>)
- move the signal to a template-less qobject
class QValueWrapperHelper : public QObject { Q_OBJECT public: QValueWrapperHelper(QObject* parent = nullptr) :QObject(parent){}; signals: void valueChanged(); };
template<typename Type> class QValueWrapper : public QValueWrapperHelper { public: QValueWrapper(QObject* parent = nullptr) :QValueWrapperHelper(parent){}; QValueWrapper(const Type & val,QObject* parent = nullptr) :QValueWrapperHelper(parent), value_(val){}; const Type & value() const {return value_;} void setValue(const Type &newValue) { if(value_ != newValue) emit valueChanged(); value_ = newValue; } private: Type value_; };
-
But Qt signals does not support template classes.
this is not strictly correct. It's MOC that can't cope with templates.
You have 3 alternatives that I can think of:
#include <wobjectdefs.h> #include <wobjectimpl.h> template<typename Type> class QValueWrapper : public QObject { W_OBJECT(QValueWrapper ) public: QValueWrapper(QObject* parent = nullptr) :QObject(parent){}; QValueWrapper(const Type & val,QObject* parent = nullptr) : QObject(parent), value_(val){} void valueChanged(Type newValue); W_SIGNAL(valueChanged, newValue) const Type & value() const {return value_;} void setValue(const Type &newValue) { if(value_ != newValue) emit valueChanged(newValue); value_ = newValue; } W_SLOT(setValue) private: Type value_; }; W_OBJECT_IMPL(QValueWrapper <Type>, template <typename Type>)
- move the signal to a template-less qobject
class QValueWrapperHelper : public QObject { Q_OBJECT public: QValueWrapperHelper(QObject* parent = nullptr) :QObject(parent){}; signals: void valueChanged(); };
template<typename Type> class QValueWrapper : public QValueWrapperHelper { public: QValueWrapper(QObject* parent = nullptr) :QValueWrapperHelper(parent){}; QValueWrapper(const Type & val,QObject* parent = nullptr) :QValueWrapperHelper(parent), value_(val){}; const Type & value() const {return value_;} void setValue(const Type &newValue) { if(value_ != newValue) emit valueChanged(); value_ = newValue; } private: Type value_; };