如何将Qmodelindex与新行关联?
-
25-10-2019 - |
题
我已经煮了一个 QAbstractListModel
其模型索引包含我绝对需要的指针来处理数据。我添加了这样的数据:
void PointListModel::addPoint(int frameNumber, QPoint const& pos)
{
PointItem *pointItem = new PointItem( frameNumber, pos );
QModelIndex newRow = this->createIndex( m_points.count(), 0, pointItem );
qDebug() << newRow.internalPointer();
beginInsertRows( newRow, m_points.count(), m_points.count() );
m_points.insert( m_points.count( ), pointItem );
endInsertRows();
emit pointAdded( pointItem, pos );
}
直到后来我才意识到论点 beginInsertRows
正在要求 父母 新行的模型索引,而不是新行的实际模型索引。
因此,在此时间点,QT给我无法提供 QModelIndex
与此特定行相关联。如何为此新行创建自己的模型索引?
解决方案
好的,我正在重写答案,因为经过一些研究,我发现自己弄错了。
添加新数据时,您不应该做任何特别的事情来创建新索引。您的代码应该看起来像这样:
PointItem *pointItem = new PointItem( frameNumber, pos );
// assume you insert a top level row, having no parent
beginInsertRows( QModelIndex(), m_points.count(), m_points.count() );
m_points.insert( m_points.count( ), pointItem );
endInsertRows();
那么您应该实施 index()
将按需创建索引和 parent()
可以确定某些索引的父的方法,但是由于您有一个列表模型,因此它可能总是返回 QModelIndex()
. 。这是 关于创建自定义模型的好文章.
这是一个工作的完整示例 QAbstractListModel
:
class MyModel: public QAbstractListModel {
Q_OBJECT
public:
virtual QModelIndex index(int row, int column = 0,
const QModelIndex &parent = QModelIndex()) const;
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
void add(int i);
private:
QList<int> list;
};
void MyModel::add(int i)
{
beginInsertRows(QModelIndex(), list.size(), list.size());
list.append(i);
endInsertRows();
}
QModelIndex MyModel::index(int row, int column,
const QModelIndex &parent) const
{
return hasIndex(row, column, parent) ? createIndex(row, column, (void*)&list[row])
: QModelIndex();
}
int MyModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
return list.size();
}
QVariant MyModel::data(const QModelIndex &index,
int role) const
{
if (!index.isValid())
return QVariant();
if (role != Qt::DisplayRole)
return QVariant();
return QVariant(QString::number(*static_cast<int*>(index.internalPointer())));
}
其他提示
我已经煮了一个QABSTRACTLISTMODEL,其模型索引包含我绝对需要的指针来处理数据。
如果您从错误的要求开始,则最终会出现错误的解决方案:)
一个 列表 模型足够简单,因此您不需要 QModelIndex
' row()
唯一定义索引地址的数据。
所以,给定一个 QModelIndex
mi
, ,当你以前做过
PointItem * item = static_cast<PointItem*>(mi.internalPointer());
你可以做
PointItem * item = plm->pointItemFromIndex(mi);
在哪里 plm
是你的 PointListModel
. 。如果您没有指向指针,则需要访问该指针 PointItem
, ,您可以这样重建它:
PointItemModel * plm = qobject_cast<PointItemModel*>(mi.model());
// check for !plm here (!mi.isValid() || qobject_cast fails)
反过来, PointListMode::pointItemFromIndex()
会做实际的工作:
PointItem * PointListMode::pointItemFromindex(const QModelIndex &mi) const {
return mi.isValid() ? m_points[mi.row()] : 0 ;
}
这是合作时最重要的事情 QAbstractListModel
在QT:精神上取代 QModelIndex
和 int row
, ,忽略它所拥有的所有其他东西(无效 QModelIndex
有 row() == -1
).
相同 QAbstractTableModel
: :在精神上减少 QModelIndex
至 int row, int column
. 。忘记其他一切。
您唯一需要完整的 QModelIndex
(包括它的 internalPointer()
或者 internalId()
是当您实现树模型时(QAbstractItemModel
).