QMap fo QMap



  • Hello,

    I built a template like this:
    QMap<QString,QMap<QString,QVariant> > data;

    How can I insert a value in this type of template?

    Many thanks in advance.

    Best Regards,

    Chobin



  • Hello,

    First you need to have a QMap "value":

    QMap< QString, QVariant > myValueMap;
    myValueMap.insert( "the answer",  42 );
    myValueMap[ "my favourite C++ framework" ] = "Qt";
    // ...
    

    Then you can populate your data QMap:

    data.insert( "key", myValueMap );
    

  • Lifetime Qt Champion

    Hi,

    QMap<QString, QVariant> entry;
    entry.insert(QStringLiteral("MyCoolKey"), 42);
    data.insert(QStringLiteral("MySecondCoolKey"), entry);
    


    • QMap allows initializer list: data.insert(QStringLiteral("MySecondCoolKey"),QMap<QString, QVariant>({std::pair<QString, QVariant>(QStringLiteral("MyCoolKey"),42)}));
    • QMap operator[] creates the element if it doesn't exist: data[QStringLiteral("MySecondCoolKey")][QStringLiteral("MyCoolKey")] = QVariant::fromValue(42);

    P.S.
    Thinking of efficiency now, generally speaking, a container of containers can be badly inefficient. fortunately Qt containers were designed to minimise this inefficiency and C++11 move constructors made it much better even with std containers. While your code is ok as Qt took upon themselves to do the hard work of making it efficient, in general if you have to store a big object as value in a container store it as a pointer:

    • No QMap<int,MyBigObject> data; data.insert(42,MyBigObject());
    • Yes but you need to remember to free the memory QMap<int,MyBigObject*> data; data.insert(42,new MyBigObject());
    • Yes QMap<int, std::shared_ptr<MyBigObject> > data; data.insert(42,std::make_shared<MyBigObject>());


  • Hi,

    Thanks for your answers.

    My goal is to write 300 parameters in a file. I'm looking to use this template

    QMap<QString,QMap<QString,QVariant> > data;

    because I'd like to write the file using QDataStream and the following operators:

    friend QDataStream & operator<<(QDataStream& str, const QMap<QString,QMap<QString,QVariant> > & fileStruct);
    friend QDataStream & operator>>(QDataStream& str, QMap<QString,QMap<QString,QVariant> > & fileStruct);
    

    Do you know a different way to reach my goal?

    Many thanks for your answers.

    Best Regards,

    Chobin



  • @Chobin said in QMap fo QMap:

    because I'd like to write the file using QDataStream and the following operators:

    Since you are using Qt Classes you don't need to write your own operators, Qt already have them implemented.

    On the other hand if you are building a massive QMap just to save it to file there is a more efficient way, yes. If you show us your code we might be more specific.



  • Hi,

    I have to write a file like this:

    Phase 1:
    parameter1 20
    parameter2 300
    parameter3 350
    Phase 2:
    parameter1 20
    parameter2 300
    parameter3 350
    Phase 3:
    parameter1 20
    parameter2 300
    parameter3 350
    Phase 4:
    parameter1 20
    parameter2 300
    parameter3 350
    Phase 5:
    parameter1 20
    parameter2 300
    parameter3 350
    ....

    As you know, I thought to use a QMap where the first key is "Phase1" and the second map key is the name of the parameters.

    QMap<QString,QMap<QString,QVariant> > fileStr;
    
    void readWriteFile::InitMap() {
        fileStr["Phase1"]["Par1"] = 1;
        fileStr["Phase1"]["Par2"] = 2;
        fileStr["Phase1"]["Par3"] = 3;
    
        fileStr["Phase2"]["Par1"] = 1;
        fileStr["Phase2"]["Par2"] = 2;
        fileStr["Phase2"]["Par3"] = 3;
    
        fileStr["Phase3"]["Par1"] = 1;
        fileStr["Phase3"]["Par2"] = 2;
        fileStr["Phase3"]["Par3"] = 3;
    }
    
    Read/Write file methods:
    
    void readWriteFile::writeFile()
    {
    QFile file( filePath + "File.dat" );
    
    if ( file.open(QIODevice::WriteOnly) )
        {
            QDataStream out( &file );
            out.setVersion(QDataStream::Qt_5_8);
            out << fileStr;
        }
    
        file.close();
    }
    
    void readWriteFile::readFile()
    {
    QFile file( filePath + "File.dat");
    
        if ( file.open(QIODevice::ReadOnly) )
        {
                QDataStream in( &file );
                in.setVersion(QDataStream::Qt_5_8);
                //Valuto se il file letto è corrotto
                if (in.status() == QDataStream::ReadCorruptData)
                    qDebug() << "File corrupt";
                else {
                    in >> fileStrRd;
                    qDebug() << "File OK";
                }
        }
    
        file.close();
    }
    

    How can I struct my code?

    Many Thanks.

    Best Regards,

    Chobin



  • Where do you currently store the number of phases, how many parameters each phase has and what are the parameters values?



  • Hi,

    the total phase number is 20 and each phase has 20 parameters. The value of these parameters can be an integer or a string.
    Each phase has the same struct of the other phases.
    I could not store the phase number in the file if I structure the file like I showed un the post above. My idea is to fill a struct or a Qt template when I read the file. The structure of these type of data is the same of the file....this is my idea.

    What do you suggest?

    Best Regards,

    Chobin



  • @Chobin
    Would a json object be an option?



  • What I would do is use QStandardItemModel + TreeView.

    you can serialise the model easily in multiple formats with this: https://github.com/VSRonin/Qt-Model-Serialisation/tree/dev (make sure to use the dev branch), there is an example in the readme that should give you a fair idea of how to structure your model.

    Since you then have to use it in QML you might want to use something like this: http://pastebin.com/70KjfZzm to overcome the annoying different treatment of multi-columns models in QML compared to QtWidgets


    additional information on the problem was given via private chat in native language


Log in to reply
 

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