arc_lupus
arc_lupus

Reputation: 4114

Convert QPair to QVariant

I have the following problem: I want to transmitt data via TCP, and wrote a function for that. For maximum reusability the function template is f(QPair<QString, QVariant> data). The first value (aka QString) is used by the receiver as target address, the second contains the data. Now I want to transfer a QPair<int, int>-value, but unfortunately I can not convert a QPair to a QVariant. The optimum would be to be able to transfer a pair of int-values without having to write a new function (or to overload the old one). What is the best alternative for QPair in this case?

Upvotes: 13

Views: 10078

Answers (3)

Mr-Auto
Mr-Auto

Reputation: 51

According to the documentation (at least from QT-5 forward):

Some types are registered automatically and do not need this macro:
QPair<T1, T2> where T1 and T2 are registered meta types

https://doc.qt.io/qt-5/qmetatype.html#Q_DECLARE_METATYPE

So all you need it this:

QPair<QString, QVariant> pair
QVariant data = QVariant::fromValue(pair)

Then converting back:

QPair<QString, QVariant> stored_pair = data.value<QPair<QString, QVariant>>(data);

And only for non-QT, non-basic types you actually need the Q_DECLARE_METATYPE macro to add the type to QMetaType

Upvotes: 1

azf
azf

Reputation: 2189

You have to use the special macro Q_DECLARE_METATYPE() to make custom types available to QVariant system. Please read the doc carefully to understand how it works.

For QPair though it's quite straightforward:

#include <QPair>
#include <QDebug>

typedef QPair<int,int> MyType;    // typedef for your type
Q_DECLARE_METATYPE(MyType);       // makes your type available to QMetaType system

int main(int argc, char *argv[])
{
    // ...

    MyType pair_in(1,2);
    QVariant variant = QVariant::fromValue(pair_in);
    MyType pair_out = variant.value<MyType>();
    qDebug() << pair_out;

    // ...
}

Upvotes: 24

Antonio Dias
Antonio Dias

Reputation: 2881

Note: this answer uses another functions to convert them, something you may consider.

You could use QDataStream to serialize the QPair to QByteArray and then convert it to QVariant, and you can the inverse process to get the QPair from a QVariant.

Example:

//Convert the QPair to QByteArray first and then
//convert it to QVariant
QVariant tovariant(const QPair<int, int> &value)
{
    QByteArray ba;
    QDataStream stream(&ba, QIODevice::WriteOnly);
    stream << value;
    return QVariant(ba);
}

//Convert the QVariant to QByteArray first and then
//convert it to QPair
QPair<int, int> topair(const QVariant &value)
{
    QPair<int, int> pair;
    QByteArray ba = value.toByteArray();
    QDataStream stream(&ba, QIODevice::ReadOnly);
    stream >> pair;
    return pair;
}

Upvotes: 4

Related Questions