私のモデルの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のツリービューは、それが一度それを示した後でないアップデート値を行います:
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;
};
最初に、 'fooChanged'を囲む' fooAboutToBeChanged'を出さずに放出してはいけません。しかしそれでも、とにかくレイアウトの変更を放つべきではありません。あなたはすでに 'beginInsertRows'と' endInsertRows'を通して 'rowsAboutToBeInserted'と' rowsInserted'シグナルを出すことによって、クライアントに変更について通知しています。 –
begin(end)のみの使用InsertRowsには結果がありません。おそらく、idxオブジェクトに問題がありますか?行インデックスをparent-> row()または0または何か他のものとして使うべきですか? –
私は 'layoutChanged'排出が唯一の問題であると主張していませんが、それは間違いなく問題です。あなたはそれをしてはいけません:) –