Известно, что, без преувеличения, основа Qt это moc и их система метатипов. В базе метатипов зарегистрированы все простые C/C++ типы и все сложные Qt типы, часто этого бывает с головой достаточно для написания программ: при использовании QVariant и QSettings или при организации вызовов типа сигнал-слот…
Но бывает, что в качестве параметра сигнала нужно передавать свою структуру или класс, или преобразовывать свой тип в QVariant. Для этого нужно зарегистрировать свой тип перед первым использованием (можно в функции main()), примерно так:
qRegisterMetaType<PhotoFormat>("PhotoFormat");
После этого его можно использовать в качестве параметра в механизме сигнал-слот.
Следующим полезным шагом - приведение нашего типа к QVariant, для этого, в дополнение к предыдущему, в заголовочном файла где располагается объявление нашего типа (на самом деле - в любом месте, но так будет логичнее) нужно разместить такую конструкцию:
Q_DECLARE_METATYPE(PhotoFormat);
Всё, после этого можно использовать подобные конструкции:
QVariant var = qVariantFromValue(PhotoFotmat("Name", 23, 22));
PhotoFormat format = qVariantValue<PhotoFormat>(var);
Ну и последнее, сохранение и восстановление нашего класса при помощи QSettings. Для этого нужно, для начала, зарегистрировать потоковые операторы:
qRegisterMetaTypeStreamOperators<PhotoFormat>("PhotoFormat");
Далее, обычно в заголовочном файле, где объявлен класс, объявляются операторы <<
и >>
:
QDataStream &operator<<(QDataStream &out, const PhotoFormat &obj);
QDataStream &operator>>(QDataStream &in, PhotoFormat &obj);
Обращаю внимание - за пределами class {};
А реализация примерно такая:
QDataStream & operator <<(QDataStream &out, const PhotoFormat &obj)
{
QString name = obj.getFormatName();
QSizeF size = obj.getSize();
qreal dst1 = obj.getTopPateDistance();
qreal dst2 = obj.getNoseChinDistance();
out << name << size << dst1 << dst2;
return out;
}
QDataStream & operator >>(QDataStream &in, PhotoFormat &obj)
{
QString name;
QSizeF size;
qreal dst1;
qreal dst2;
in >> name >> size >> dst1 >> dst2;
obj.setFormanName(name);
obj.setSize(size);
obj.setTopPateDistance(dst1);
obj.setNoseChinDistance(dst2);
return in;
}
По сути, сериализация класса. Более подробная информация - на странице справки по классу QMetaType, и можно глянуть тут: http://www.crossplatform.ru/?q=node/281