Search code examples
qtqlist

How to iterate a class in a Qlist with QlistIterator


I want to display the full contents of a Qlist containing instances of my Airports class. This class itself contains another Qlist that integrates the instances of a runways class.

Here is an exemple of the structure of the Qlist m_apList:

    m_apList    <2 éléments>    QList<Airport>
        [0] @0x29265df0 Airport
            m_code  "LFPO"  QString
            m_name  "PARIS/ORLY"    QString
            m_position  @0x29265df0 QGeoCoordinate
            m_runway    <6 éléments>    QList<Runway>
                [0] @0x292660d0 Runway
                    m_freqIls   110.3   double
                    m_ils   1   int
                    m_ilsRdh_ft 50  int
                    m_ilsSlope_deg  3.0 double
                    m_length    7874    int
                    m_loc   19  int
                    m_name  "02"    QString
                    m_position  @0x292660d0 QGeoCoordinate
                    m_qfu   19  int
                    m_width 197 int
                [1] @0x292661b8 Runway
                    m_freqIls   108.5   double
                    m_ils   1   int
                    m_ilsRdh_ft 54  int
                    m_ilsSlope_deg  3.0 double
                    m_length    11975   int
                    m_loc   63  int
                    m_name  "06"    QString
                    m_position  @0x292661b8 QGeoCoordinate
                    m_qfu   63  int
                    m_width 148 int
                [2] @0x29266270 Runway
                [3] @0x29266358 Runway
                [4] @0x29266468 Runway
                [5] @0x292664f0 Runway
            m_runwayLen 11900   int
            m_unknown1  5000    int
            m_unknown2  0   int
        [1] @0x29265f50 Airport
            m_code  "LFPP"  QString
            m_name  "LE PLESSIS/BELLEVILL"  QString
            m_position  @0x29265f50 QGeoCoordinate
            m_runway    <4 éléments>    QList<Runway>
                [0] @0x292666e0 Runway
                    m_freqIls   0.0 double
                    m_ils   0   int
                    m_ilsRdh_ft 50  int
                    m_ilsSlope_deg  0.0 double
                    m_length    2297    int
                    m_loc   0   int
                    m_name  "07"    QString
                    m_position  @0x292666e0 QGeoCoordinate
                    m_qfu   66  int
                    m_width 66  int
                [1] @0x29266800 Runway
                [2] @0x29266888 Runway
                [3] @0x29265548 Runway
            m_runwayLen 2700    int
            m_unknown1  0   int
            m_unknown2  0   int

According to the example of Qt here http://doc.qt.io/qt-5/qlistiterator.html#details, it is necessary to create an iterator to roll out the Qlist. But I get this error message "no match for 'operator<<' (operand types are 'QDebug' and 'const Airport')" with this code:

void listAirports(){
    QListIterator<Airport> i(m_apList);
    while (i.hasNext())
        qDebug() << i.next();
}

I think it's necessary to iterate at lower levels to access each child, then child.

How can we simply scroll through the entire Qlist content?

Thanks for your help.

PS : Showing the Add method

class AirportsModel : public QAbstractListModel
{
    Q_OBJECT

public:
    AirportsModel(QObject *parent = Q_NULLPTR):QAbstractListModel(parent){
    }
    enum AirportsRoles{
        PositionRole = Qt::UserRole + 1,
        OACICodeRole
    };

    void readFromTXT(const QString &filename){

        QFile file(filename);
        if(!file.open(QFile::ReadOnly | QFile::Text))
            return;

        QTextStream in(&file);
        while (!in.atEnd()) {


            QString line = in.readLine();
            QStringList elements = line.split(",");
            if (elements[0] == "A"){
                QString code = elements[1];
                QString name = elements[2];
                double latitude = elements[3].toDouble();
                double longitude = elements[4].toDouble();
                double elevation = elements[5].toDouble();
                int unk1 = elements[6].toInt();
                int unk2 = elements[7].toInt();
                int runwayLen = elements[8].toInt();

                //Add Airport to m_apList
                Airport ap(code, name, latitude, longitude, elevation, unk1, unk2, runwayLen);
                addAirport(ap);
                }

            else if (elements[0] == "R")
            {
                QString name = elements[1];
                int qfu = elements[2].toInt();
                int length_ft = elements[3].toInt();
                int width = elements[4].toInt();
                int ils = elements[5].toInt();
                double freq_Ils = elements[6].toDouble();
                int loc = elements[7].toInt();
                double latitude = elements[8].toDouble();
                double longitude = elements[9].toDouble();
                double elevation_ft = elements[10].toDouble();
                double ilsSlope_deg = elements[11].toDouble();
                int ilsRdh_ft = elements[12].toInt();

                Runway rw(name, qfu, length_ft, width, ils, freq_Ils,loc,latitude,longitude,elevation_ft,ilsSlope_deg,ilsRdh_ft);

                //Add runway to Airport
                m_apList[m_apIndex].addRunway(rw);
            }
        }//while
    } //readFromTXT

    void addAirport(const Airport &point){
        int mCount = rowCount();
        m_apIndex = mCount;
        beginInsertRows(QModelIndex(), mCount, mCount);
        m_apList << point;
        endInsertRows();
    }

    Q_INVOKABLE int rowCount(const QModelIndex & parent = QModelIndex()) const{
        Q_UNUSED(parent)
        return m_apList.count();
    }

    QVariant data(const QModelIndex & index, int role=Qt::DisplayRole) const {
        ...
    }

protected:
        QHash<int, QByteArray> roleNames() const {
            ...
        }

private:
    QList<Airport> m_apList;        //Les données du fichier sont enregistrés dans une liste de Airports nommée m_apList
    int m_apIndex;
};


#endif // AIRPORTSMODEL_H

And here is the Airport class

#ifndef AIRPORT_H
#define AIRPORT_H

#include <QGeoCoordinate>
#include <QString>


class Runway
{
public:
    Runway(QString name, int qfu, int length_ft, int width, int ils, double freq_Ils,
           int loc, double latitude, double longitude, double elevation_ft, double ilsSlope_deg, int ilsRdh_ft)
        : m_name(name), m_qfu(qfu), m_length(length_ft), m_width(width),
          m_ils(ils), m_freqIls(freq_Ils), m_loc(loc), m_ilsSlope_deg(ilsSlope_deg), m_ilsRdh_ft(ilsRdh_ft)
    {
        m_position.setLatitude(latitude);
        m_position.setLongitude(longitude);
        m_position.setAltitude(elevation_ft);
    }

    QString nameRunway() const { //lecture du code OACI
        return m_name;
    }

private:
    QGeoCoordinate m_position;
    QString m_name;
    int m_qfu;
    int m_length;
    int m_width;
    int m_ils;
    double m_freqIls;
    int m_loc;
    double m_ilsSlope_deg;
    int m_ilsRdh_ft;

};


class Airport
{
public:
    Airport(QString code, QString name, double latitude, double longitude,
            double elevation_ft, int unknown1, int unknown2, int runwayLenght_ft)
        :m_code(code), m_name(name), m_unknown1(unknown1), m_unknown2(unknown2),
          m_runwayLen(runwayLenght_ft) {

        m_position.setLatitude(latitude);
        m_position.setLongitude(longitude);
        m_position.setAltitude(elevation_ft);
    }
    void setPosition(const QGeoCoordinate &c) { //Affectation des nouvelles coordonnees de position
        m_position = c;
    }
    QGeoCoordinate position() const{
        return m_position; //Lecture des coordonnees de position
    }
    QString oaciCode() const { //lecture du code OACI
        return m_code;
    }
    QString airportName() const {
        return m_name;
    }
    int runwayLength() const { //lecture du pays
        return m_runwayLen;
    }
    void addRunway(const Runway &runway){
        m_runway << runway;
    }
    private:
        QGeoCoordinate m_position;
        QString m_code;
        QString m_name;
        int m_unknown1;
        int m_unknown2;
        int m_runwayLen;
        QList<Runway> m_runway;
};

#endif // AIRPORT_H

Solution

  • You simply cannot print out your Airport object with qDebug() just like that. What you can do is just serialize an Airport object yourself, e.g.:

    void listAirports()
    {
      foreach (const Airport &airport, m_apList)
      {
        // Print out the airport's properties
        qDebug() << "Code:" << airport.m_code; // Might be a member functions
        qDebug() << "Name:" << airport.m_name;
        // etc.
    
        // Print out ranaways
        const auto &ranways = airport.ranways();
        foreach (const Ranway &ranway, ranways)
        {
          qDebug() << "m_freqIls" << ranway.m_freqIls;
          qDebug() << "m_ilsSlope_deg  " << ranway.m_ilsSlope_deg;
          // etc.
        }
      }
    }