2013-03-27 98 views
2

我正在試驗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); 
} 

parentQModelIndex(-1,-1,0x0,AbstractModel(0xfa9690))rootIndexQModelIndex(-1,-1,0x0,QObject(0x0)),他們是不相等的,這就是爲什麼事件不會引發。需要更多時間來認識爲什麼會發生這種情況......

P.P.P.S.在對同一個應用程序的純C++版本進行了一些實驗後,我發現了這個錯誤的原因。在_q_rowsInserted以上的父母是我們在beginInserRows()提交的值和rootIndexQPersistentModelIndex類的對象。 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內部另一個更明確,具體的問題,我會考慮的。)

+0

這個問題鏈接到OCaml?如果沒有,請刪除ocaml標籤。 – Thomash 2013-03-27 14:44:41

+0

我認爲最好把它當作'因爲我不直接調用C++方法,它們都被包裝成OCaml值。 – Kakadu 2013-03-27 15:44:40

+0

據我所知,沒有公共的QModelIndex(int,int)構造函數,所以我很驚訝它編譯。你有沒有試過QModelIndex()? – MartinJ 2013-03-27 22:13:31

回答

0

創建QModelIndex正確的做法是空車返回QModelIndex如果行== - 1或列== - 1。重要的是不要將結果指針放在結果QModelIndex中。如果你願意的話,某些東西可能無法正常工作。