[Qt-interest] Fwd: typedef on the same underlying type and Q_REGISTER_METATYPE
MARTIN Pierre
hickscorp at gmail.com
Tue Sep 13 22:30:23 CEST 2011
i did a typo in my previous solution, and changed a bunch of stuff so here is the code of my full functional example:
Wrapper class:
#ifndef TypeWrapper_hpp
#define TypeWrapper_hpp
#include <QDataStream>
namespace RE {
#ifndef DECLARE_TYPE_WRAPPER
#define DECLARE_TYPE_WRAPPER(Cls, typ) \
class Cls : public TypeWrapper<typ> { \
public: \
Cls () : TypeWrapper() {} \
Cls (typ const &t) : TypeWrapper(t) {} \
Cls (Cls const &c) : TypeWrapper(c) {} \
};
#endif
#ifndef DECLARE_INDIRECT_WRAPPER
#define DECLARE_INDIRECT_WRAPPER(Cls, Bas, typ) \
class Cls : public Bas { \
public: \
Cls () : Bas() {} \
Cls (typ const &t) : Bas(t) {} \
Cls (Cls const &c) : Bas(c) {} \
};
#endif
template<typename T>
class TypeWrapper {
public:
// Constructors.
TypeWrapper () : _t() {}
TypeWrapper (T const &t) : _t(t) {}
TypeWrapper (TypeWrapper<T> const &w) : _t(w._t) {}
// Cast operators.
operator T () const { return _t; }
// Assignment operators.
TypeWrapper<T>& operator= (T const &t) { _t = t; return *this; }
// QDataStream friend serialization stuff.
friend QDataStream& operator<< (QDataStream& s, TypeWrapper<T> const &w) { return s << w._t; }
friend QDataStream& operator>> (QDataStream& s, TypeWrapper<T> &w) { return s >> w._t; }
private:
T _t;
};
}
#endif
Basically, this class wraps any base type to another with assignment operators.
To declare a type, do (In my example i declare one then two inheriting the first one):
namespace RE {
namespace T {
DECLARE_TYPE_WRAPPER (Ratio, double);
DECLARE_INDIRECT_WRAPPER (PositiveRatio, Ratio, double);
DECLARE_INDIRECT_WRAPPER (NegativeRatio, Ratio, double);
}
}
And then register them as usual:
Q_DECLARE_TYPEINFO(RE::T::Ratio, Q_MOVABLE_TYPE);
Q_DECLARE_METATYPE(RE::T::Ratio);
Q_DECLARE_TYPEINFO(RE::T::PositiveRatio, Q_MOVABLE_TYPE);
Q_DECLARE_METATYPE(RE::T::PositiveRatio);
Q_DECLARE_TYPEINFO(RE::T::NegativeRatio, Q_MOVABLE_TYPE);
Q_DECLARE_METATYPE(RE::T::NegativeRatio);
Then, here is how my editors factory looks like for createEditor:
[...........]
// Ratio of any kind.
else if (t==qMetaTypeId<RE::T::Ratio>() || t==qMetaTypeId<RE::T::PositiveRatio>() || t==qMetaTypeId<RE::T::NegativeRatio>())
return new WgtRatioEditor(p);
[...........]
The factory looks like this for the valuePropertyName method:
[...........]
else if (t>=qMetaTypeId<RE::T::Ratio>() && t<=qMetaTypeId<RE::T::NegativeRatio>())
return "value";
[...........]
This way, my automatically-generated edition forms know how to handle this metatype id too.
And then the editor widget itself:
#ifndef WgtRatioEditor_h
#define WgtRatioEditor_h
// Base class.
#include <QtGui/QDoubleSpinBox>
// Required stuff.
#include <RELibrary/RETypes>
#include <QtCore/QVariant>
namespace REA {
class WgtRatioEditor : public QDoubleSpinBox {
Q_OBJECT
Q_PROPERTY(QVariant value READ value WRITE setValue USER true NOTIFY valueChanged)
public:
// Constructors.
Q_INVOKABLE WgtRatioEditor (QWidget *p=0)
: QDoubleSpinBox(p), _inSetValue(false) {
setSingleStep (.05);
connect(this, SIGNAL(valueChanged(double)), this, SLOT(self_valueChanged(double)));
}
// Accessors.
QVariant value () const {
double v = QDoubleSpinBox::value();
if (_t==qMetaTypeId<RE::T::Ratio>())
return QVariant::fromValue(RE::T::Ratio(v));
else if (_t==qMetaTypeId<RE::T::PositiveRatio>())
return QVariant::fromValue(RE::T::PositiveRatio(v));
else
return QVariant::fromValue(RE::T::NegativeRatio(v));
}
void setValue (QVariant const &v) {
_inSetValue = true;
_t = v.userType();
bool positive = _t!=qMetaTypeId<RE::T::NegativeRatio>();
bool negative = _t!=qMetaTypeId<RE::T::PositiveRatio>();
setRange (negative ? -1.0 : 0.0, positive ? 1.0 : 0.0);
RE::T::Ratio const *r = (RE::T::Ratio const*)v.constData();
QDoubleSpinBox::setValue (*r);
_inSetValue = false;
}
protected slots:
void self_valueChanged (double v) {
if (!_inSetValue)
emit valueChanged();
}
private:
bool _inSetValue;
int _t;
signals:
void valueChanged ();
};
}
#endif
It allows edition of types inheriting from the "RE::T::Ratio" base class.
i hope it could help someone some day.
Pierre.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20110913/4a6dfd92/attachment.html
More information about the Qt-interest-old
mailing list