2016-04-27 25 views
1

私のモデルの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; 
}; 
+0

最初に、 'fooChanged'を囲む' fooAboutToBeChanged'を出さずに放出してはいけません。しかしそれでも、とにかくレイアウトの変更を放つべきではありません。あなたはすでに 'beginInsertRows'と' endInsertRows'を通して 'rowsAboutToBeInserted'と' rowsInserted'シグナルを出すことによって、クライアントに変更について通知しています。 –

+0

begin(end)のみの使用InsertRowsには結果がありません。おそらく、idxオブジェクトに問題がありますか?行インデックスをparent-> row()または0または何か他のものとして使うべきですか? –

+0

私は 'layoutChanged'排出が唯一の問題であると主張していませんが、それは間違いなく問題です。あなたはそれをしてはいけません:) –

答えて

0

QMLのListViewは、たとえばディレクトリツリーのようなツリー構造を表示するのには適していません。 QAbstractListModelから継承されたリストモデルでのみ機能します。 QAbstractItemModelからモデルを派生させた場合は、それをリストのように動作させるように特殊化する必要があります。

Qt 5.5以降、モジュールQtQuick.Controls(v1.4)にQML TreeViewが存在します。これを試してみてください。

+0

質問に間違いがあります。もちろん私はQTreeViewとQMLのTreeViewを使用します。 –

関連する問題