0

I have a custom class called Foo, and I store instances of this class in a vector:

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

I want to display name property in listView, so i create a model, and then fill it with names:

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); } 

Now, after I click the item in the UI, I want to have access to this whole Foo class, and it's properties and methods, so I use loop to find my object:

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); } } } 

And it does work, but I feel it's not very optimal way of doing it(what if two objects have the same name?)

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

Is there a better solution to this problem? I can ditch QVector or Model/View listView or anything else stupid in this code.


TL;DR:
Basically, I want to have one property of an object(QString name) displayed in a listView (or listWidget), and after i click it, I want to have access to every property and method of its class.

==============
EDIT:

So i made my own model using 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; }; 

I still use a loop to fill this model with 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); 

And then i still use a loop to get a second property of my desired object:

 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; } } } 


I'm duplicating data just like with QStandartItemModel before, right?
I tried to use QAbstractListModel as Konstantin T said, but I don't think I understand Models good enough and used it in a correct way...

1 Answer 1

1

Using QStandardItemModel almost always is a bad idea. You are duplicating your data in QVector and Model. It become very difficult to keep data consistent.

Better way in your case is to use QAbstractListModel instead.

Sign up to request clarification or add additional context in comments.

2 Comments

I used QAbstractListModel and edited my post to show my results. Could you look at it?
@FilthyCasual It depend on where you get the data. Usualy you get data from a file or from a data base and so on, but not from the Vector you've just created. Though you can store your data in Vector (or any other container) inside you model. In MainWindow::on_view_clicked you don't need to iterate through model. You should use myOwnModel::data() to get the data you want.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.