2017-04-19 5 views
2

Qt example for QAbstractItemModel을 사용하고 Item을 주어진 index으로 업데이트하려고합니다.데이터가 업데이트 될 때 QAbstractItemModel 뷰를 업데이트하는 방법

emit DataChanged을 사용해 보았지만 작동하지 않습니다. 보기가 업데이트되지 않았습니다..

내가 원하는 무엇가 : 당신이 버튼을 클릭하면, 인덱스 0, 동물의 type에서 업데이트 데이터가 변경됩니다 것, 그것은 될 것이다 여기에

은 예입니다 라이온.

#include <QAbstractListModel> 
#include <QStringList> 
#include <qqmlcontext.h> 
//![0] 
class Animal 
{ 
public: 
    Animal(const QString &type, const QString &size); 
//![0] 

    QString type() const; 
    QString size() const; 

    void setType(QString q) { 
     m_type = q; 
    } 

private: 
    QString m_type; 
    QString m_size; 
//![1] 
}; 

class AnimalModel : public QAbstractListModel 
{ 
    Q_OBJECT 
public: 

    Q_INVOKABLE void test() ; 
    void setName(const QString &name); 
    enum AnimalRoles { 
     TypeRole = Qt::UserRole + 1, 
     SizeRole 
    }; 

    AnimalModel(QObject *parent = 0); 
//![1] 
//! 
//! 
    void setContext(QQmlContext *ctx) { 
     m_ctx = ctx; 
    } 

    void addAnimal(const Animal &animal); 

    int rowCount(const QModelIndex & parent = QModelIndex()) const; 

    QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; 
    QHash<int, QByteArray> roleNames() const; 

protected: 

private: 
    QList<Animal> m_animals; 
    QQmlContext* m_ctx; 

signals: 
    void dataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight); 
//![2] 
}; 
//![2] 

model.h

#include "model.h" 
#include "qDebug" 
Animal::Animal(const QString &type, const QString &size) 
    : m_type(type), m_size(size) 
{ 
} 

QString Animal::type() const 
{ 
    return m_type; 
} 

QString Animal::size() const 
{ 
    return m_size; 
} 




AnimalModel::AnimalModel(QObject *parent) 
    : QAbstractListModel(parent) 
{ 
} 

void AnimalModel::addAnimal(const Animal &animal) 
{ 
    beginInsertRows(QModelIndex(), rowCount(), rowCount()); 
    m_animals << animal; 
    endInsertRows(); 
} 

void AnimalModel::test() { 

    m_animals[0].setType("Lion"); 
    emit dataChanged(QModelIndex(),QModelIndex()); 

    //I also tried: 
    QModelIndex topLeft = createIndex(0,0); 
    emit dataChanged(topLeft, topLeft); 


} 

int AnimalModel::rowCount(const QModelIndex & parent) const { 
    Q_UNUSED(parent); 
    return m_animals.count(); 
} 

QVariant AnimalModel::data(const QModelIndex & index, int role) const { 
    if (index.row() < 0 || index.row() >= m_animals.count()) 
     return QVariant(); 

    const Animal &animal = m_animals[index.row()]; 
    if (role == TypeRole) 
     return animal.type(); 
    else if (role == SizeRole) 
     return animal.size(); 
    return QVariant(); 
} 

//![0] 
QHash<int, QByteArray> AnimalModel::roleNames() const { 
    QHash<int, QByteArray> roles; 
    roles[TypeRole] = "type"; 
    roles[SizeRole] = "size"; 
    return roles; 
} 
//![0] 

model.cpp

#include "model.h" 

#include <QGuiApplication> 
#include <qqmlengine.h> 
#include <qqmlcontext.h> 
#include <qqml.h> 
#include <QtQuick/qquickitem.h> 
#include <QtQuick/qquickview.h> 

//![0] 
int main(int argc, char ** argv) 
{ 
    QGuiApplication app(argc, argv); 

    AnimalModel model; 
    model.addAnimal(Animal("Wolf", "Medium")); 
    model.addAnimal(Animal("Polar bear", "Large")); 
    model.addAnimal(Animal("Quoll", "Small")); 

    QQuickView view; 
    view.setResizeMode(QQuickView::SizeRootObjectToView); 
    QQmlContext *ctxt = view.rootContext(); 
    ctxt->setContextProperty("myModel", &model); 
//![0] 

    view.setSource(QUrl("qrc:view.qml")); 


    view.show(); 

    return app.exec(); 
} 

MAIN.CPP

import QtQuick 2.0 
import QtQuick 2.4 
import QtQuick.Controls 1.3 
import QtQuick.Window 2.2 
import QtQuick.Dialogs 1.2 
import QtQuick.Layouts 1.2 
import QtQml.Models 2.1 
import QtQuick.Controls.Styles 1.2 


//![0] 
ListView { 
    width: 200; height: 250 

    model: myModel 
    delegate: Text { text: "Animal: " + type + ", " + size } 

    MouseArea { 
     anchors.fill: parent 
     cursorShape: Qt.PointingHandCursor 
     onClicked: { 

     } 
    } 
    Button { 
     anchors.bottom: parent.bottom 
     width:50; height:50 
     text:"click" 
     onClicked: { 
      myModel.test() 
     } 

    } 

} 
//![0] 

View.qml

왜 작동하지 않는지 아십니까? 감사합니다.

+0

당신이 문서화 된 서명은'dataChanged' 신호를 구현하기 위해 시도? – derM

+0

안녕하세요, 먼저 시도한 것은 첫 번째'data'가 업데이트 되었기 때문에'emit dataChanged (0,0)'와 같은 것을 작성하는 것입니다. 그러나 dataChanged는'int'를 받아들이지 않습니다.'QModelIndex (0)'과 같은 것을 쓸 수 없기 때문에 여기에서 작성해야 할 부분이 조금 있습니다. 이것은 바보 같은 물건일지도 모르지만 나는 그런 개념에 관해 정말로 초보자 다. –

+0

나는 또한'QModelIndex topLeft = createIndex (0,0); 시도했다. emit dataChanged (topLeft, topLeft); ' –

답변

2

서브 클래스의 신호를 다시 정의하지 마십시오.

은 (model.h에서) 다음 줄을 제거하고 예상대로 작동합니다 :

signals: 
    void dataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight); 

는 또한이 dataChanged()를 호출 할 때 유효한 QModelIndex를 지정해야합니다. 이것은 올바른 : http://doc.qt.io/qt-5/qabstractitemmodel.html#dataChanged :

// I also tried: 
    QModelIndex topLeft = createIndex(0,0); 
    emit dataChanged(topLeft, topLeft); 
+2

또는'emit QAbstractListModel :: dataChanged (index (0), index (0)); ' – derM

+0

둘 다 감사합니다! –

관련 문제