Passing Objects in QMap to QMap



  • Hi
    I have a QMap with a Object
    e.g.
    QMap<QString, Graha> grahaMap;

    I passed this grahaMap into a function as a reference.
    e.g.
    void calcRootD1(QMap<QString, Graha> &grahaMap);

    inside this calcRootD1 function
    I access the Graha object inside the map and insert it into a QList.
    I then inser tthis QList of Grahas e.g. QList <Graha> into a QMap.
    Within the function, I iterate through it to prove that the values have been added correctly.
    The print out confirms that it is there.

    This is the code that does that:
    @
    void DivChartBaseClass::calcRootD1(QMap<QString, Graha> &grahaMap)
    {

    for(int j = 1; j <= 12; j++){
        double ascLongitude = grahaMap.value(kAsc).longitude;
        if(degreesToSeconds( ascLongitude ) >= d1Border[j-1] && degreesToSeconds( ascLongitude ) < d1Border[j])
        {
            rootD1Ascendant = j;
        }
    }
    
    for(int j = 1; j <= 12; j++){
    
        QList<Graha> signHasG;
        QList<Graha> houseHasG;
    
    
        QMapIterator<QString, Graha> i(grahaMap);
        while (i.hasNext()) {
            i.next();
    
            if(degreesToSeconds( i.value().longitude ) >= d1Border[j-1] && degreesToSeconds( i.value().longitude ) < d1Border[j])
            {
    
                d1GrahaInSign.insert(i.key(), j);
                d1GrahaInHouse.insert(i.key(), howManyHousesAway(rootD1Ascendant, j));
                QMap<QString, int> houseNumAndSign;
                //ASSERT that rootD1Ascendant is not 0
                houseNumAndSign.insert(kHouseNum, howManyHousesAway(rootD1Ascendant, j));
                houseNumAndSign.insert(kSignNum, j);
                Graha g = i.value();
                g.chartMap.insert(kD1, houseNumAndSign);
                qDebug() << "***************************";
                //qDebug() << rootD1Ascendant;
                qDebug() << i.key()<< ":" <<  g.chartMap.value(kD1).value(kHouseNum);
                qDebug() << i.key() << ":" << g.chartMap.value(kD1).value(kSignNum);
                qDebug() << "**************************";
    
                grahaMap[i.key()] = g;
    
                signHasG.push_back(g);
                houseHasG.push_back(g);
            }
        }
        //qDebug() << j;
        d1SignHasGrahas.insert(j, signHasG );
        d1HouseHasGrahas.insert(howManyHousesAway(rootD1Ascendant, j), houseHasG );
    }
    
    QMapIterator<int, QList<Graha> > j(d1HouseHasGrahas);
    while(j.hasNext()){
        j.next();
    
        QListIterator<Graha> k(j.value());
        while (k.hasNext()){
            qDebug() << j.key() << " has " << k.next().name;
        }
    }
    
    QMapIterator<int, QList<Graha> > l(d1SignHasGrahas);
    while(l.hasNext()){
        l.next();
    
        QListIterator<Graha> m(l.value());
        while (m.hasNext()){
            qDebug() << l.key() << " has " << m.next().name;
        }
    }
    qDebug() << "Done";
    

    }
    @

    So at this point, I felt confident that everything will go smoothly...
    However, when I call a different function in the same class to iterate through the QMap mentioned above that SHOULD contain the QList <Graha>, the program crashes.
    With the qDebug() placed in different lines, my theory is that it crashes because the Graha objects is not retained...but I may be wrong....
    I even thought that objects are kept in memory once (by increasing reference count) they are inserted into a QMap or Qlist...
    Here is the function I call to iterate through the QMap (D1 class inherits from DivChartBaseClass and DivChartBaseClass has a QMap<int, QList<Graha> > d1SignHasGrahas):

    @
    void D1::calcThisChartFromRootD1(){
    qDebug() << "D1 - calcThisChartFromRootD1";
    QMapIterator<int, QList<Graha> > j(d1SignHasGrahas);

    while(j.hasNext())
    {
        j.next();
        qDebug() << j.key();
    
        if(!j.value().isEmpty()){
            QListIterator<Graha> k(j.value());
            while(k.hasNext()){
                k.next();
                qDebug() << j.key() << "HAS" << k.next().name;
            }
        }
    }
    

    }
    @

    What's the solution to make the QMap retain the data and NOT crash the application...???

    Thank you very much :)



  • Hi there,

    QObjects don't have (accessible) copy constructors or assignment operators. Thus they can not be stored themselves in QList or QMap or any other container that depends on copying/storing elements by value. Instead, you should store pointers to QObjects. This is by design, see
    https://qt-project.org/doc/qt-4.8/object.html#identity-vs-value
    and the section "No copy constructor or assignment operator" in
    https://qt-project.org/doc/qt-4.8/qobject.html



  • Hi
    Ok..sorry I don't get it..
    I have changed my code but I think I'm basically stuck on the same concept.

    I have a QMap declared in a class.
    e.g.
    QMap<int, QList<Graha> > d1SignHasGrahas;

    In that class I have a function that takes in a QMap that has Grahas as values.
    @
    QMap<QString, Graha> DivChartBaseClass::calcD1GrahaMap(QMap<QString, Graha> grahaMap)
    {
    ........
    }
    @

    Inside function, I intend to fill in the values for the QMap declared above (this QMap ....QMap<int, QList<Graha> > d1SignHasGrahas ).

    So, what I did was create a for loop and then create a QList <Graha> signList where I store the Grahas and then I insert the QList<Graha> signList to the d1SignHasGrahas QMap.

    @
    for(int j = 1; j <= 12; j++){
    QList <Graha> signList;
    QMapIterator<QString, Graha> i(grahaMap);
    while (i.hasNext()) {
    i.next();

            if(degreesToSeconds( i.value().longitude ) >= d1Border[j-1] && degreesToSeconds( i.value().longitude ) < d1Border[j])
            {
                d1GrahaInSign.insert(i.key(), j);
                d1GrahaInHouse.insert(i.key(), howManyHousesAway(rootD1Ascendant, j));
    
                //------------------------------
                QMap<QString, int> houseNumAndSign;
                //ASSERT that rootD1Ascendant is not 0
                houseNumAndSign.insert(kHouseNum, howManyHousesAway(rootD1Ascendant, j));
                houseNumAndSign.insert(kSignNum, j);
                Graha g = i.value();
                g.chartMap.insert(kD1, houseNumAndSign);
                grahaMap[i.key()] = g;
                signList.push_back(g);
            }
        }
        d1SignHasGrahas.insert(j, signList);
    }
    

    @

    Which one should I change into a pointer?

    When I iterate through the d1SignHasGrahas QMap.
    It correctly tries to iterate the QList inserted. However, when I try to print a Graha detail that is on the list, it crashes. So it seems like the Graha doesn't get saved.

    Thank you very much for the help...


  • Lifetime Qt Champion

    Hi,

    Have a look at "QObject":http://qt-project.org/doc/qt-4.8/qobject.html documentation, it'll explain and point to the other documents explaining why you can't copy a QObject or QObject derived class.

    Since you Graha class is a QObject, you must use pointer to it.



  • Hi
    Ok...I got it this time...
    thanks for pointing me to the right direction.
    Changed
    QMap<int, QList<Graha> > d1SignHasGrahas;
    to
    QMap<int, QList<Graha*> > d1SignHasGrahas;
    ..............
    and when filling in the QList
    I used
    QList<Graha*> signList;
    QList<Graha*> houseList;

    instead of
    QList<Graha> signList;
    QList<Graha> houseList;

    And finally, when testing the QMap with the QList to graha pointers...
    Old fashioned for loop worked better than the iterators.
    I've commented out the iterators that wasn't working for me..
    Maybe iterators cant work with pointers in the inside layer??
    Is it possible to use Iterators in this case?

    @

    inline void printXHasGrahas(QMap<int, QList<Graha*> > xHasGrahas){

    for(int i = 0; i < xHasGrahas.count() ; i++){
        //QList<Graha*>* graha = d1SignHasGrahas[i];
        qDebug() << xHasGrahas[i].count();
    
        for(int j = 0; j < xHasGrahas[i].count(); j++ )
        {
            qDebug()<< i <<":"<< xHasGrahas[i].at(j)->name;
        }
    
    }
    
    /*
    QMapIterator<int, QList<Graha*> > y(xHasGrahas);
    qDebug() << "inside printXHasGrahas";
    while (y.hasNext()){
        y.next();
    
        qDebug() << y.key();
    
        QListIterator<Graha*> z(y.value());
        while(z.hasNext())
        {
            z.next();
    
            qDebug() << "Inside printSignHasGrahas Helper";
            //qDebug() << y.key() << ":" << z.next().name;
            qDebug() << y.key() << ":" << z.next()->name;
        }
    }
    */
    

    }

    @

    My Graha class is declared
    class Graha{
    ......
    }

    Not
    class Graha : public QObject{} (In fact this doesn't work)

    In Qt, any class even if it doesn't explicitly inherit from QObject is still a QObject?????

    Thank you very much.



  • No not every class is automatically a QObject. If your class Graha is not a QObject, and it declares a proper copy constructor and assignment operator, storing it by value in containers does work.

    About the iterator: They also work normally. I guess you have a problem in line 29. Why do you call z.next() a second time in a single loop iteration when you call it in line 25 already? This will very likely crash on the final iteration.



  • Thank you very much...

    You are right about the iterator..
    i've made the changes and it worked....

    Thank you very much.


Log in to reply
 

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