Ich geerbte QAbstractItemModel-Klasse für mein Modell. Um auf einfache Weise neue Elemente an das Modell einfügen I nächsten Methode geschrieben:QAbstractItemModel dynamische Elementeinfügung
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});
}
Es funktioniert gut mit QListView, aber QML des TreeView keine Aktualisierungen Werte, nachdem sie einmal zeigte es:
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 Klasse:
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;
};
Zuallererst sollten Sie "fooChanged" nicht ohne einschließendes 'fooAboutToBeChanged' ausgeben. Aber selbst dann sollten Sie keinen Layoutwechsel vornehmen. Sie informieren die Clients bereits über die Änderung, indem Sie die Signale "rowsAboutToBeInserted" und "rowsInserted" über "beginInsertRows" und "endInsertRows" ausgeben. –
Mit nur begin (end) InsertRows haben kein Ergebnis. Vielleicht gibt es ein Problem mit dem IDX-Objekt? Sollte ich Zeilenindex als Eltern-> Zeile() oder 0 oder irgendetwas anderes verwenden? –
Ich behaupte nicht, dass die 'layoutChanged' Emission das einzige Problem ist, aber es ist definitiv ein Problem, und Sie sollten es nicht tun :) –