[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