Qt - QVector 和模型视图 - 从 listView 获取自定义类的最佳方法是啥?
Posted
技术标签:
【中文标题】Qt - QVector 和模型视图 - 从 listView 获取自定义类的最佳方法是啥?【英文标题】:Qt - QVector and Model View - what's the best way to get a custom class from a listView?Qt - QVector 和模型视图 - 从 listView 获取自定义类的最佳方法是什么? 【发布时间】:2020-02-04 13:31:03 【问题描述】:我有一个名为 Foo
的自定义类,我将此类的实例存储在一个向量中:
class Foo
public:
QString name;
int second_property;
//...
QVector<Foo> foos = test1, test2, test3;
我想在listView
中显示name
属性,所以我创建了一个模型,然后用名称填充它:
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);
现在,在我单击 UI 中的项目后,我想访问整个 Foo
类,以及它的属性和方法,所以我使用循环来查找我的对象:
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:
基本上,我想在listView
(或listWidget
)中显示一个对象的一个属性(QString name
),然后单击它,我想访问其类的每个属性和方法。
============== 编辑:
所以我使用 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;
;
我仍然使用循环来用QVector<Foo> foos
name
属性填充这个模型:
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);
然后我仍然使用循环来获取所需对象的第二个属性:
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 一样,对吧? 我尝试像Konstantin T 所说的那样使用 QAbstractListModel,但我认为我对模型的理解不够好并以正确的方式使用它...
【问题讨论】:
【参考方案1】:使用 QStandardItemModel 几乎总是一个坏主意。您正在 QVector 和模型中复制数据。保持数据一致变得非常困难。
在您的情况下,更好的方法是改用QAbstractListModel。
【讨论】:
我使用了 QAbstractListModel 并编辑了我的帖子以显示我的结果。可以看看吗? @FilthyCasual 这取决于您从哪里获取数据。通常您从文件或数据库等中获取数据,但不是从您刚刚创建的 Vector 中获取数据。尽管您可以将数据存储在模型内的 Vector(或任何其他容器)中。在MainWindow::on_view_clicked
中,您不需要遍历模型。您应该使用myOwnModel::data()
来获取您想要的数据。以上是关于Qt - QVector 和模型视图 - 从 listView 获取自定义类的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
Qt容器类的对象模型及应用(线性结构篇:对于QList来说,sharable默认是false的,但对于接下来讲的QVector来说,sharable默认是true)
再谈QVector与QByteArray——Qt的写时复制(copy on write)技术