如何有效地查找 QAbstractTableModel::data 中的项目?
Posted
技术标签:
【中文标题】如何有效地查找 QAbstractTableModel::data 中的项目?【英文标题】:How to efficiently lookup items in QAbstractTableModel::data? 【发布时间】:2021-11-01 19:43:51 【问题描述】:据我所见,Qt 文档和大多数在线示例假定我们对data()
中基于(列、行)的查找感到满意。但是如果我的表是基于自定义结构的呢?例如让我们有:
struct MyDrive
QString serialNo;
QString user;
QString pc;
QString ipAddress;
QString category;
;
serialNo
是关键。因此,来自外部的任何操作(想象模型已实现侦听器)都使用它来删除/修改项目,使 QMap
成为理想的候选对象。
但是如何将这个结构与QModelIndex
的数据联系起来呢? QAbstractTableModel::data
要求以 (column,row) 作为键的数据,使其更适合 QVector<QVector>>
或类似的东西(我读到的地方我应该避免在 data()
中使用具有非恒定访问时间的容器(如 map)) .
我可以想象使用一个以QModelIndex
作为键和serialNo
作为值的映射,它将用作我的(基于序列号的)映射的键,但这看起来非常低效——QModelIndex
地址毕竟具体的条目(序列号,用户,个人电脑,...),所以我们会一遍又一遍地复制同一个项目。我也在考虑使用<serialNo, MyDrive*>
映射,但这只是一个丑陋的设计决策的解决方法。
我不敢相信我是第一个遇到这种情况的人,那么它通常是如何解决的?
【问题讨论】:
您需要继承 QAbstractItemModel 并覆盖索引。使用 createIndex 并将指针传递给您的数据结构 @linuxfever 是的,与此同时我已经想通了,但仍然......你会传递给指针什么?整体结构?对于每一列?对我来说似乎有点低效...... 你能描述一下你希望你的表格视图是什么样子吗?是否以 user、pc、ipadress 和 category 作为列的单行? @linuxfever 完全正确(加上序列号)。提供记录但与它们一起工作没有问题。在我看来,我必须选择是否需要一种有效的方式来修改它们或呈现它们,但不是两者兼而有之。 我正在为您准备答案。我假设您有很多 MyDrive 实例。这些是如何存储的?矢量您可以使用 QAbstractItemModel::match 按序列查找项目 qt help 并将所有必要的数据输入表中。这将允许您不使用容器,但这是一个效率如何的问题......
第二种解决方案是 AbstractItemModel Reference 的子类。现在你可以通过实现 data() 函数来做你想做的事并使用任何容器。
【讨论】:
【参考方案2】:我可能误解了您所面临的问题,但我们开始吧。我假设你有很多MyDrive
的实例。这是 QAbstractTableModel 子类的(不完整)实现。诀窍是将 MyDrive 的正确实例传递给适当的 QModelIndex。当您稍后修改或访问该索引中的数据时,您不再需要使用 serialNo 了,因为该索引的内部指针是您在创建该索引时传递的 MyDrive 实例:
class MyTable : public QAbstractTableModel
public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
auto* my_drive = static_cast<MyDrive*>(index.internalPointer());
auto drive_key = my_drive->serialNo;
// use the key if you desire for lookups etc
//...
// return your data;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole)
auto* my_drive = static_cast<MyDrive*>(index.internalPointer());
auto drive_key = my_drive->serialNo;
// use they key again if you like
QModelIndex index(int row, int column, const QModelIndex &parent) const
// insert checks here for parent and to ensure row and column are within appropriate bounds etc
// your returned index will now store your MyDrive instance which you will later access from the data and setData methods
return createIndex(row, column, m_data + row);
private:
// array of MyDrive instances
MyDrive* m_data;
;
【讨论】:
好的,但是现在您将如何从外部更改特定的 MyDrive? IE。现在我想修改 seriaNo = 1234 的记录(例如更改其 IP 地址)。这就是我所说的意思——现在你让它易于呈现,但不容易从外部修改(现在我知道我应该更具体地说明修改步骤)。以上是关于如何有效地查找 QAbstractTableModel::data 中的项目?的主要内容,如果未能解决你的问题,请参考以下文章