我爲我的模型繼承了QAbstractItemModel類。爲了方便地插入新項目的模式,我寫了一個方法:QAbstractItemModel動態項插入
void addItem(MyData *parent, MyData *children) {
QModelIndex idx = createIndex(parent->row(), 0, parent);
if (!idx.isValid()) {
return;
}
int childCount = parent->getChildCount();
beginInsertRows(idx, childCount, childCount);
parent->addChild(children);
endInsertRows();
emit layoutChanged(QList<QPersistentModelIndex>{idx});
}
這與而QListView運作良好,但QML的TreeView控件不更新值後一次顯示了它:
int main(int argc, char ** argv) {
Q_INIT_RESOURCE(ui);
QApplication application(argc, argv);
MyModel model;
for (int i = 0; i < 10; ++ i) {
MyData *firstLevelItem = new MyData(i);
for (int k = 0; k < 3; ++ k) {
MyData *secondLevelItem = new MyData(i);
model.addItem(firstLevelItem, secondLevelItem);
}
model.addItem(model.getRootItem(), firstLevelItem);
}
QQuickView view;
QQmlContext *context = view.rootContext();
context->setContextProperty("MyModel", &model);
view.setSource(QUrl("qrc:///ui/form.qml"));
view.show();
QTreeView t;
t.setModel(&model);
t.show();
MyData *data = new MyData(2281488);
model.addItem(model.getRootItem(), data);
// t displays changes, view - not
return application.exec();
}
MyData的類:
class MyModel;
class MyData: public QObject {
Q_OBJECT
public:
explicit MyData() :
QObject() {
_parent = nullptr;
}
~MyData() {
qDeleteAll(_data);
}
// getters/setters
MyData *getChildItem(int index) const {
if (index < 0 || index >= _data.size()) {
return nullptr;
}
return _data[index];
}
int getChildCount() const {
return _data.size();
}
MyData *parent() const {
return _parent;
}
int row() const {
if (_parent) {
return _parent->_data.indexOf(const_cast<MyData *>(this));
} else {
return 0;
}
}
private:
void addChild(MyData *data) {
if (data) {
if (data->_parent) {
_parent->removeChild(data);
}
data->_parent = this;
_data << data;
}
}
void removeChild(MyData *data) {
_data.removeAll(data);
}
// some private fields
MyData *_parent;
QVector<MyData *> _data;
friend class MyModel;
};
首先,如果沒有封閉的'fooAboutToBeChanged',你不應該發出'fooChanged'。但即使如此,你仍然不應該發佈佈局改變。您已通過'beginInsertRows'和'endInsertRows'發出'rowsAboutToBeInserted'和'rowsInserted'信號,通知客戶有關更改。 –
只使用開始(結束)InsertRows沒有結果。也許有idx對象的問題?我應該使用行索引作爲父 - 行()或0或其他? –
我並不是說'layoutChanged'發射是唯一的問題,但這絕對是一個問題,你不應該這樣做:) –