QML ListView在endInsertRows()之后不更新信息 我正在实验C++、QML和OcAML。现在我正在修复一个奇怪的问题:如果我向模型中添加新行,QML不会自动更新。是的,我知道beginInsetRows()…endInsertRows()
我的模型有一列和一行。我想再添加一行,然后调用QML ListView在endInsertRows()之后不更新信息 我正在实验C++、QML和OcAML。现在我正在修复一个奇怪的问题:如果我向模型中添加新行,QML不会自动更新。是的,我知道beginInsetRows()…endInsertRows(),listview,models,qml,Listview,Models,Qml,我的模型有一列和一行。我想再添加一行,然后调用beginInsertRows(QModelIndex(-1,-1),1,1),进行一些计算并调用endInsertRows()。我在qt5/qtbase/src/corelib/itemmodels/qabstractemmodel.cpp void QAbstractItemModel::endInsertRows() { Q_D(QAbstractItemModel); qDebug() << "Insert QAbstra
beginInsertRows(QModelIndex(-1,-1),1,1)
,进行一些计算并调用endInsertRows()
。我在qt5/qtbase/src/corelib/itemmodels/qabstractemmodel.cpp
void QAbstractItemModel::endInsertRows()
{
Q_D(QAbstractItemModel);
qDebug() << "Insert QAbstractItemModel::endInsertRows()";
QAbstractItemModelPrivate::Change change = d->changes.pop();
d->rowsInserted(change.parent, change.first, change.last);
qDebug() << "emitting rowsInserted("<<change.parent<<","<<change.first<<","<<change.last<<")";
emit rowsInserted(change.parent, change.first, change.last, QPrivateSignal());
}
然后我开始思考ListView是如何实现的,以及它如何处理关于添加新行的信号。grep命令的输出真的让我大吃一惊:
......./qt5/qtdeclarative/src/quick/items$ grep rowsInserted qquicklistview*
......./qt5/qtdeclarative/src/quick/items$
那么,你能解释一下ListView是如何处理模型中的更改的,以及用什么正确的方式来表示已经插入了行吗
另外,我不知道是否有任何源文件会有用,但这是,这是
p.p.S.调试后,我意识到出了什么问题
void QQuickVisualDataModel::_q_rowsInserted(const QModelIndex &parent, int begin, int end)
{
Q_D(QQuickVisualDataModel);
if (parent == d->m_adaptorModel.rootIndex)
_q_itemsInserted(begin, end - begin + 1);
}
有parent
是QModelIndex(-1,-1,0x0,AbstractModel(0xfa9690))
但是rootIndex
是QModelIndex(-1,-1,0x0,QObject(0x0))
并且它们不相等,这就是事件未引发的原因。需要更多的时间来了解为什么会发生这种情况
p.p.p.S.在对同一应用程序的纯C++版本进行了一些实验之后,我发现了这个错误的原因。在成员\u q\u rowsInserted
中,父级是我们在beginInserRows()
中提交的值,rootIndex
是类QPersistentModelIndex
的对象rootIndex
通常等于QModelIndex(-1,-1,NULL,NULL)。您还应该知道类QModelIndex
的运算符==比较该类的所有4个字段
也就是说,如果我们调用beginInsertRows(QModelIndex(),…)
,那么parent
将等于rootIndex
,因为这些索引都等于QMoldeIndex(-1,-1,NULL,NULL)
。但是如果我们调用beginInsertRows(createIndex(-1,-1),…)
,那么我们的父对象将是QModelIndex(-1,-1,NULL,)
,它显然不相等rootIndex
,因为NULL!=。因此,调用beginInsertRows(createIndex(…),…)
似乎不是一个好主意
有人能给我解释一下Qt内部发生了什么吗
(现在最好关闭这个问题,重新打开另一个关于Qt内部的更具体的问题。我会考虑一下。)创建QModelIndex的正确方法是,如果行==-1或列==-1,则返回空的QModelIndex。不要将指向模型的指针放在结果QModelIndex中,这一点很重要。如果您这样做,某些东西可能无法正常工作。此问题是否与OCaml相关?如果不是,请删除OCAML标签。我认为最好是这样做,因为我不直接调用C++方法,它们都被封装到OcAML值。据我所知,没有公开的QMeMealDead(int,int)构造函数,所以我很惊讶编译。您是否尝试过QModelIndex()?QModelIndex()与QModelIndex(-1,-1)相同
void QQuickVisualDataModel::_q_rowsInserted(const QModelIndex &parent, int begin, int end)
{
Q_D(QQuickVisualDataModel);
if (parent == d->m_adaptorModel.rootIndex)
_q_itemsInserted(begin, end - begin + 1);
}