繼續上次的例子,對於list才說只有行,討論列是沒有意義的。
bool insertRows(int row, int count, const QModelIndex &parent);
bool removeRows(int row, int count, const QModelIndex &parent);
在文檔中,insertRows是這麼寫的,在支援這個操作的models中,在給定的row之前插入count數目的row到model中,插入的都是parent的孩子。
如果row=0,這些行被插入到parent存在的行,如果row=rowCount(),也是如此。如果parent無孩子,這些rows作為一個單列被插入。在最後明確強調了必須使用beginInsertRows和endInsertRows,所以在實現這個的時候,這兩個函數才是關鍵,看這兩個函數,這兩個在QAbstractItemModel虛基類中是protect,所以他們只是工具函數。
首先beginInsertRows
void beginInsertRows(const QModelIndex &parent, int first, int last);參數first是rows開始處,last是結束處,所以是插入長度是last-first+1,這兩個參數是有insertRows的row和count參數決定。
可是實際時,我們在插入行時,只是可以在原有的資料之後添加一些資料,所以first=現在的行數(行數從0開始,所以現在的行數就是新的行),last=first+count-1。
在我的例子代碼中
bool StringListModel::insertRows(int row, int count, const QModelIndex &/*parent*/){ beginInsertRows(QModelIndex(),row,row + count -1); for (int i = 0;i < count;++i) { //鏈表插入的時候,row大於size()時按size()來算 m_slist.insert(row,QString()); } endInsertRows(); return true;}
addmodel直接修改模型
void StringListModel::addmodel(const QString &c){ insertRows(rowCount(QModelIndex()),1,QModelIndex()); m_slist.replace(rowCount(QModelIndex())-1,c);}
現在insertRow的兩個參數可以很好的理解了。
也可以這麼來
void StringListModel::addmodel(const QString &c){ // insertRows(rowCount(QModelIndex()),1,QModelIndex()); insertRow(rowCount(QModelIndex())); m_slist.replace(rowCount(QModelIndex())-1,c);}
insertRow內部實現就是使用的insertRows,我們插入之後只是預設值(這裡是Null 字元串,你可以自己修改),所以我們必須把預設值換成我們需要的。在調用beginInsertRows時,它會發出rowsAboutToBeInserted,通知所有與這個model有關的視圖更新,這也是必須使用這些函數的原因,不然只是修改了底層資料,而上層沒反應。