2014-02-17 1 views
5

QAbstractListModel에서 파생 된 모델을 QML 뷰에 바인딩하는 방법을 알아 냈습니다.QAbstractListModel 기반 모델에 새 항목을 추가 할 때 QML 뷰가 업데이트되지 않음

하지만 다음에 피곤한 것은 작동하지 않습니다. 새로운 아이템이 모델에 추가되면 QML 뷰는 업데이트되지 않습니다. 왜 그런가요?

DataObject.h

class DataObject { 
    public: 
     DataObject(const QString &firstName, 
        const QString &lastName): 
      first(firstName), 
      last(lastName) {} 

     QString first; 
     QString last; 
}; 

SimpleListModel.h

class SimpleListModel : public QAbstractListModel 
{ 
    Q_OBJECT 

    enum /*class*/ Roles { 
     FIRST_NAME = Qt::UserRole, 
     LAST_NAME 
    }; 

    public: 
     SimpleListModel(QObject *parent=0); 
     QVariant data(const QModelIndex &index, int role) const; 
     Q_INVOKABLE int rowCount(const QModelIndex &parent = QModelIndex()) const; 
     QHash<int, QByteArray> roleNames() const; 
     void addName(QString firstName, QString lastName); 

    private: 
     Q_DISABLE_COPY(SimpleListModel); 
     QList<DataObject*> m_items; 
}; 

SimpleListModel.cpp

SimpleListModel::SimpleListModel(QObject *parent) : 
    QAbstractListModel(parent) 
{ 
    DataObject *first = new DataObject(QString("Firstname01"), QString("Lastname01")); 
    DataObject *second = new DataObject(QString("Firstname02"), QString("Lastname02")); 
    DataObject *third = new DataObject(QString("Firstname03"), QString("Lastname03")); 

    m_items.append(first); 
    m_items.append(second); 
    m_items.append(third); 
} 

QHash<int, QByteArray> SimpleListModel::roleNames() const 
{ 
    QHash<int, QByteArray> roles; 

    roles[/*Roles::*/FIRST_NAME] = "firstName"; 
    roles[/*Roles::*/LAST_NAME] = "lastName"; 

    return roles; 
} 

void SimpleListModel::addName(QString firstName, QString lastName) 
{ 
    DataObject *dataObject = new DataObject(firstName, lastName); 

    m_items.append(dataObject); 

    emit dataChanged(this->index(m_items.size()), this->index(m_items.size())); 
} 

int SimpleListModel::rowCount(const QModelIndex &) const 
{ 
    return m_items.size(); 
} 

QVariant SimpleListModel::data(const QModelIndex &index, int role) const 
{ 
    //--- Return Null variant if index is invalid 
    if(!index.isValid()) 
     return QVariant(); 

    //--- Check bounds 
    if(index.row() > (m_items.size() - 1)) 
     return QVariant(); 

    DataObject *dobj = m_items.at(index.row()); 

    switch (role) 
    { 
     case /*Roles::*/FIRST_NAME: 
      return QVariant::fromValue(dobj->first); 

     case /*Roles::*/LAST_NAME: 
      return QVariant::fromValue(dobj->last); 

     default: 
      return QVariant(); 
    } 
} 

AppCore.h

class AppCore : public QObject 
{ 
    Q_OBJECT 
    Q_PROPERTY(SimpleListModel *simpleListModel READ simpleListModel CONSTANT) 

    public: 
     explicit AppCore(QObject *parent = 0); 
     SimpleListModel *simpleListModel() const; 

    public slots: 
     void addName(); 

    private: 
     SimpleListModel *m_SimpleListModel; 

}; 

APPCORE.CPP

AppCore::AppCore(QObject *parent) : 
    QObject(parent) 
{ 
    m_SimpleListModel = new SimpleListModel(this); 
} 

SimpleListModel *AppCore::simpleListModel() const 
{ 
    return m_SimpleListModel; 
} 

void AppCore::addName() 
{ 
    m_SimpleListModel->addName("FirstnameNEW", "LastnameNEW"); 
} 

MAIN.CPP

int main(int argc, char *argv[]) 
{ 
    QGuiApplication a(argc, argv); 

    QQuickView *view = new QQuickView(); 
    AppCore *appCore = new AppCore(); 

    qRegisterMetaType<SimpleListModel *>("SimpleListModel"); 

    view->engine()->rootContext()->setContextProperty("appCore", appCore); 
    view->setSource(QUrl::fromLocalFile("main.qml")); 
    view->show(); 

    return a.exec(); 
} 

main.qml

,
// ... 
ListView { 
    id: myListView 
    anchors.fill: parent 
    delegate: myDelegate 
    model: appCore.simpleListModel 
} 

MouseArea { 
    anchors.fill: parent 
    onClicked: { 
     appCore.addName() 
     console.log('rowCount: ' + appCore.simpleListModel.rowCount()) 
    } 
} 
//... 

답변

10

당신이 신호를

void SimpleListModel::addName(QString firstName, QString lastName) 
{ 
    DataObject *dataObject = new DataObject(firstName, lastName); 

    // tell QT what you will be doing 
    beginInsertRows(ModelIndex(),m_items.size(),m_items.size()); 

    // do it 
    m_items.append(dataObject); 

    // tell QT you are done 
    endInsertRows(); 

} 

를 방출하는 대신 beginInsertRows 및 endInsertRows를 호출해야이 두 기능이 모두 필요한 신호

1

당신은 QAbstractItemModel의 의미를 무시하고를 방출한다.

  • 데이터 변화 신호 : 그들은 방출해야 이후 데이터가 변경 한 모델이 발광해야 신호 두 가지가있다. 데이터 변경은 기존 항목의 값 변경입니다. 모델의 다른 변경 사항은 이 아니고 데이터 변경이라고합니다. 여기서 용어는 특별한 의미가 있습니다.

  • 구조 변화 신호 : 그들은 구조적 및 변경 후 전에 방출되어야한다. 구조 변경은 항목을 추가하거나 제거하는 것입니다. beginXxxYyyendXxxYyy 도우미 기능은 이러한 신호를 방출합니다.