Cast a QVariant to a QList<customObject>



  • Hello everyone,

    I did a search in the forum but didn't find anything. (If I'm wrong, just link me the threads please).

    I have some customs classes, and I need to map them with some QVariant.
    What I'm doing is a constructor from a QVariant to instantiate them from the QVariant, and an operator QVariant() const in order to use static_cast to cast the object to a QVariant.

    But now I'm facing one problem with QList. I have for example a QVariant containing a QList of QMap<QString, QVariant>. A QMap<QString, QVariant> represent my object A. I'm able to cast a QMap to a A and vice versa.

    My question is from a QVariant like this (QList<QMap<QString, QVariant> >), how can I cast it to a QList of my custom type (QList<A>).

    Code:
    @#include <QDebug>

    using namespace std;

    class A
    {
    public:
    int value;

    public:
        A () {cout << "Default constructor" << endl;}
        A (int arg)
        {   
            this->value = arg;
        }   
        A (QVariant variant) throw (int)
        {   
            cout << "Constructor from variant" << endl;
            if (!variant.canConvert(QVariant::Map))
                throw 1;
            QMap<QString,QVariant> mapVariant = variant.toMap();
            this->value = mapVariant["value"].toInt();
        }   
        A operator=(A& copy)
        {   
            cout << "Constructor by copy" << endl;
            this->value = copy.value;
            return (*this);
        }   
        virtual ~A ()
        {}  
    
        operator QVariant() const
        {   
            QMap<QString,QVariant> mapAns = QMap<QString,QVariant>();
            mapAns.insert("value", this->value);
    
            return mapAns;
        }   
    

    };
    Q_DECLARE_METATYPE(A);

    Q_DECLARE_METATYPE(QList<A>);
    int main(int argc, const char *argv[])
    {
    cout << "[Log] Beginning of the prog(" << argv[0] << ")" << endl;

    QList<QMap<QString, QVariant> > listVariant = QList<QMap<QString, QVariant> >();
    
    QMap<QString, QVariant> mapA1 = QMap<QString,QVariant>();
    QMap<QString, QVariant> mapA2 = QMap<QString,QVariant>();
    QMap<QString, QVariant> mapA3 = QMap<QString,QVariant>();
    QMap<QString, QVariant> mapA4 = QMap<QString,QVariant>();
    mapA1.insert("value", 4); 
    mapA2.insert("value", 9); 
    mapA3.insert("value", 3); 
    mapA4.insert("value", 2); 
    
    listVariant.append(mapA1);
    listVariant.append(mapA2);
    listVariant.append(mapA3);
    listVariant.append(mapA4);
    
    QList<A> listA = static_cast<QList< A > >(listVariant);
    qDebug() << "[Debug] listA (" << listA << ")";
    
    cout << "[Log] End of the prog" << endl;
    return 0;
    

    }
    @



  • Little up to clarify my claim. I made an even simpler example without any custom type, and I don't get the cast.

    I create a QStringList, I pass it to a QVariant, and then I want to cast it to a QList<QString>.

    The SL object is composed by my "test 1" and "test 2" QString. But my listResult is completely empty.
    @
    Q_DECLARE_METATYPE(QList<QString>);
    @

    @
    QStringList SL = QStringList();
    SL.append("test 1");
    SL.append("test 2");
    qDebug() << "[Debug] SL (" << SL << ")";

    QList<QString> listResult = QVariant(SL).value<QList<QString> >();
    qDebug() << "[Debug] listResult (" << listResult << ")";
    @


  • Lifetime Qt Champion

    Hi,

    QStringList and QList<QString> are two different thing (Not a typedef in this case).

    Try with @QStringList listResult = QVariant(SL).value<QStringList>();@



  • Ok, so that was a bad example to show my goal hahahaaaaa :(

    I have a QList<QVariant>, and the QVariant inside are mapped to a custom type. (see the code above on the first post).

    So from a QList<QVariant> I want to cast it to a QList<CustomType>.

    The problem is that it cast without error from the compiler in the below example, but the listA is completely empty.

    My current example from the first post:
    @
    QList<QVariant> listVariant = QList<QVariant>();

    QMap<QString, QVariant> mapA1 = QMap<QString,QVariant>();
    QMap<QString, QVariant> mapA2 = QMap<QString,QVariant>();
    QMap<QString, QVariant> mapA3 = QMap<QString,QVariant>();
    QMap<QString, QVariant> mapA4 = QMap<QString,QVariant>();
    mapA1.insert("value", 4); 
    mapA2.insert("value", 9); 
    mapA3.insert("value", 3); 
    mapA4.insert("value", 2); 
    
    listVariant.append(QVariant(mapA1));
    listVariant.append(QVariant(mapA2));
    listVariant.append(QVariant(mapA3));
    listVariant.append(QVariant(mapA4));
    
    qDebug() << "[Debug] QVariant(listVariant) (" << QVariant(listVariant) << ")";
    

    //output: [Debug] QVariant(listVariant) ( QVariant(QVariantList, (QVariant(QVariantMap, QMap(("value", QVariant(int, 4) ) ) ) , //QVariant(QVariantMap, QMap(("value", QVariant(int, 9) ) ) ) , QVariant(QVariantMap, QMap(("value", QVariant(int, 3) ) ) ) , //QVariant(QVariantMap, QMap(("value", QVariant(int, 2) ) ) ) ) ) )

    QList<A> listA = QVariant(listVariant).value<QList<A> >();
    
    
    qDebug() << "[Debug] listA (" << listA << ")";
    

    //Output: [Debug] listA ( () )

    @


  • Lifetime Qt Champion

    static_cast is normally used to cast a pointer to an object to one of it's derivative, or a numeric datatype to another (i.e int to char etc...) without any check.

    What you are trying to achieve is to transform a QVariantList containing QVariantHash into a class that does not inherit at all from QVariant.

    The QVariant operator is basically used to put your class in a QVariant (it is used where you would otherwise have to use QVariant::fromValue)

    The value<T> function will work on a QVariant if the object in contains already is of the type T or can be converted to type T. AFAIK QVariantHash cannot be converted to A.

    Hope this helps


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.