C++ добавление данных из struct в QComboBox

170
17 января 2018, 17:10

Имеется struct

#ifndef WAYPOINTDATA_H
#define WAYPOINTDATA_H
struct WaypointData
{
    short iD;
    short iconId;
    double lng;
    double lat;
    double alt;
    int minAltitude;
    int state;    
};
#endif // WAYPOINTDATA_H

Данные в struct добавляеются через чтения .json файла.

QString filename = QFileDialog::getOpenFileName(this,
                                                    tr("Load"), "",
                                                    tr("File (*.wpf)"));
    if(!filename.isEmpty()){
        QByteArray val;
        QFile file(filename);
        file.open(QIODevice::ReadOnly | QIODevice::Text);
        val = file.readAll();
        file.close();
        QJsonDocument d = QJsonDocument::fromJson(val);
        QJsonObject obj = d.object();
        int i = 0;
        MapView->waypointData.clear();
        for(const QString &key: obj.keys() ){
            QString line = obj[key].toString();
            QStringList elements = line.split(",");
            double lng = elements[0].toDouble();
            double lat = elements[1].toDouble();
            double alt = elements[2].toDouble();
            WaypointData* w = new WaypointData();
            w->alt = alt;
            w->lng = lng;
            w->lat = lat;
            w->state = 0;
            QString id= key;
            w->iD = id.remove(0,8).toInt();
            MapView->AddWaypoint(*w);
        }
        MapView->DrawWaypoints();
    }

Есть также QComboBox - WayPointBox.

Интересует, как добавить данные из struct в QComBox в формате как на картинке ниже.

Т.е получается - w->iD[0], w->lng[0], w->lat[0], w->alt[0]

Answer 1

Грязный и быстрый способ. Просто слепить все необходимые данные в строку, и добавить ее в комбобокс(если надо, исходную структуру тоже можно положить):

Q_DECLARE_METATYPE(WaypointData)
//...
static const QString format("%1, %2, %3, %4")
WaypointData data;
ui->WayPointBox->addItem(format.arg(data.iD)
                               .arg(data.lng)
                               .arg(data.lat)
                               .arg(data.alt),
                         QVariant::fromValue(data));

Красивый но чуть более сложный способ. Сделать собственную модель:

class WaypointDataModel : public QAbstractListModel{
    QVector<WaypointData> _data;
public:
    WaypointDataModel(QObject *paretn):
        QAbstractListModel(parent)
    {
        //Как-то заполняем _data
        //Можно недостающие данные получить через параметры конструктора
    }
    QVariant data(const QModelIndex &index, int role) const{
        switch(role){
            case Qt::DispalyRole:
            case Qt::EditRole:
                return _toString(_data[index.row()]);
            default:
                return QVariant();
        }
    }
    int rowCount(const QModelIndex &parent) const{
        if(parent.isValid()){
            return 0;
        }
        return _data.size();
    }
private:
    QString _toString(const WaypointData &waypointData) const{
        static const QString format("%1, %2, %3, %4");
        return format.arg(data.iD)
                     .arg(data.lng)
                     .arg(data.lat)
                     .arg(data.alt);
    }
};

Там где у вас должен заполняться комбобокс делаем так:

ui->WayPointBox->setModel(new WaypointDataModel(ui->WayPointBox));

При желании можно добавить методы доступа к данным в модели, сделать их редактируемыми, комбобокс разноцветным, можно подключить модель к десятку разных представлений, короче можно все что душе угодно. А главное, весь код отвечающий за данные сосредоточен в модели.

PS Код писал в браузере, могут быть ошибки

Answer 2

Просто конвертируем структуру в строку по вашему формату:

QString toStr(WaypointData *w) {
    return QString::number(w->iD)+", "+QString::number(w->lng)+", "+QString::number(w->lat)+", "+QString::number(w->alt)+";";
}

И набиваем список структур в бокс:

std::vector<std::shared_ptr<WaypointData>> points;
//...
for(auto point = points.begin(); point!=points.end(); ++point)
    ui->WayPointBox->addItem(toStr(*point));

Прекрасно работает.

READ ALSO
Проект Qt собирается, но не запускается

Проект Qt собирается, но не запускается

Собрал проект Qt, но при попытке запуска из Qt Creator в консоли сборки следующие сообщения:

189
Получить размер текстуры в памяти

Получить размер текстуры в памяти

Загружаю текстуру функцией:

241
Проверка вложений в файлах MS Office

Проверка вложений в файлах MS Office

Есть сервер, на который могут загружаться файлы MS Word и MS ExcelКак, используя java, убедиться, что они не содержат вложения в виде exe-файлов, jar-ников...

210
Приложение не хочет устанавливаться на android 6.0

Приложение не хочет устанавливаться на android 6.0

ЗдравствуйтеПриложение нормально устанавливается , работает и отлаживается на версиях 4

556