我正在試驗C++,QML和OCaml。現在我正在解決一個奇怪的問題:如果我將新行添加到我的模型中,QML不會自行更新。是的,我知道關於beginInsetRows()... endInsertRows()。QML ListView不會更新信息後endInsertRows()
我的模型有1列和1行。我想再添加一行,我打電話給beginInsertRows(QModelIndex(-1,-1), 1, 1)
,做一些計算並且打電話給endInsertRows()
。我添加了一些調試輸出到qt5/qtbase/src/corelib/itemmodels/qabstractitemmodel.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());
}
根據需要發出我的應用程序日誌信號rowsInserted
。
Going to call AbstractModel::beginInsertRows
Calling AbstractModel::rowCount
rowCount = 1
Going to call AbstractModel::endInsertRows
Insert QAbstractItemModel::endInsertRows()
emitting rowsInserted(QModelIndex(-1,-1,0x0,AbstractModel(0x11d3680)) , 1 , 1)
End inserting rows. cpp_data.length = 2
Sending event to change model
Call update (0,0)...(1,0)
Going to call AbstractModel::dataChanged
Calling AbstractModel::parent
比我開始思考如何實現ListView以及它如何處理有關添加新行的信號。 grep命令的輸出真的驚訝了我:
......./qt5/qtdeclarative/src/quick/items$ grep rowsInserted qquicklistview*
......./qt5/qtdeclarative/src/quick/items$
所以,u能請解釋一下我的ListView如何處理變化的模型,什麼是信號的行已經插入正確的方法是什麼?
P.S.我不知道是否有任何源文件會有用,但這是whole source tree,這是the most interesting place in the sources
P.P.S. debuggin後,我意識到什麼是錯的
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++版本進行了一些實驗後,我發現了這個錯誤的原因。在_q_rowsInserted
以上的父母是我們在beginInserRows()
提交的值和rootIndex
是QPersistentModelIndex
類的對象。 rootIndex
通常是相等的QModelIndex(-1,-1,NULL,NULL)。你也應該知道類QModelIndex
的運算符==比較了這個類的所有4個字段。
I.e.如果我們呼叫beginInsertRows(QModelIndex(),...)
比parent
將等於rootIndex
,因爲這些指標都等於QMoldeIndex(-1,-1,NULL,NULL)
。但是如果我們打電話beginInsertRows(createIndex(-1,-1),....)
比我們的父母將是QModelIndex(-1,-1,NULL,<non-null pointer to our model>)
,並且它顯然不會等於rootIndex
,因爲NULL!=。所以,打電話給beginInsertRows(createIndex(....),....)
似乎不是個好主意。
有人可以解釋我在Qt內部會發生什麼嗎?
(也許現在是更好地關閉這個問題,並重新打開關於Qt內部另一個更明確,具體的問題,我會考慮的。)
這個問題鏈接到OCaml?如果沒有,請刪除ocaml標籤。 – Thomash 2013-03-27 14:44:41
我認爲最好把它當作'因爲我不直接調用C++方法,它們都被包裝成OCaml值。 – Kakadu 2013-03-27 15:44:40
據我所知,沒有公共的QModelIndex(int,int)構造函數,所以我很驚訝它編譯。你有沒有試過QModelIndex()? – MartinJ 2013-03-27 22:13:31