Qt - QVector и Model View - каков наилучший способ получить пользовательский класс из listView? - PullRequest
0 голосов
/ 04 февраля 2020

У меня есть собственный класс с именем Foo, и я храню экземпляры этого класса в векторе:

    class Foo{
    public:
       QString name;
       int second_property;
    }
    //...
    QVector<Foo> foos = {test1, test2, test3};

Я хочу отобразить свойство name в listView, поэтому я создаю модель, а затем заполните ее именами:

in .h
    QStandardItemModel model;
    QStandardItem* root;
    QStandardItem* item;

in .cpp
    root = model.invisibleRootItem();
    ui->listView->setModel(&model);
foreach(Foo foo, foos){
        item = new QStandardItem(foo.name);
        root->appendRow(item);
    }

Теперь, после того как я щелкну элемент в пользовательском интерфейсе, я хочу получить доступ ко всему этому классу Foo, его свойствам и методам. поэтому я использую l oop, чтобы найти свой объект:

void MainWindow::on_listView_clicked(const QModelIndex &index)
{
    foreach(Foo foo, foos){
        if(foo.name==index.data().toString()){
           qDebug()<<"You found the object! Second property: " + foo.second_property);
        }
    }
}

И это работает, но я чувствую, что это не очень оптимальный способ сделать это (что, если два объекта имеют один и тот же name? )

==============

Есть ли лучшее решение этой проблемы? Я могу отказаться от QVector или Model / View listView или чего-то еще глупого в этом коде. TL; DR:
По сути, я хочу, чтобы одно свойство объекта (QString name) отображалось в listView (или listWidget), и после того, как я щелкнул по нему, я хочу получить доступ к каждому свойству и метод его класса.

============== РЕДАКТИРОВАТЬ:

Таким образом, я сделал свою собственную модель, используя QAbstractListModel :

 class myOwnModel : public QAbstractListModel
{
    Q_OBJECT
public:
    myOwnModel(const QStringList &strings={""}, QObject *parent = nullptr);


    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    QVariant data(const QModelIndex &index, int role) const override;

    Qt::ItemFlags flags(const QModelIndex &index) const;
    bool setData(const QModelIndex &index, const QVariant &value,
    int role = Qt::EditRole);
    bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex());

private:
     QStringList stringList;
};

Я все еще использую al oop, чтобы заполнить эту модель QVector<Foo> foos name properties:

    myOwnModel* myModel = new myOwnModel();
    for(int row=0; row<foos.size(); row++){
        myModel->insertRows(row,1);
        QModelIndex index = myModel->index(row,0);
        myModel->setData(index,foos[row].name);
    }
    ui->view->setModel(myModel);

А потом я все еще использую al oop, чтобы получить второе свойство моего желаемого объекта:

    void MainWindow::on_view_clicked(const QModelIndex &index)
    {
        for(int i=0;i<foos.size();i++){
            if(index.data().toString()==foos[i].name){
                qDebug() << "You found " << foos[i].name + " and the second property is " << foos[i].second_property;
            }
        }
    }

Я дублирую данные так же, как с QStandartItemModel раньше, верно? Я пытался использовать QAbstractListModel , как сказал Константин Т , но я не думаю, что понимаю модели достаточно хорошо и использовал их правильно ...

1 Ответ

1 голос
/ 04 февраля 2020

Использование QStandardItemModel почти всегда плохая идея. Вы дублируете свои данные в QVector и Model. Поддерживать согласованность данных становится очень трудно.

В вашем случае лучше использовать QAbstractListModel .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...