2013-11-25 3 views
1

Qt 5를 배우기 시작했고 오랫동안 한 지점에서 멈추었습니다.QML에서 C++ 객체의 목록 속성에 액세스하는 방법

두 클래스가 있습니다. ScoreHandler는 ScoreRecords 목록을 처리합니다. C++에서이 두 클래스를 만들고 ScoreHandler의 인스턴스를 컨텍스트 속성으로 설정합니다. 이제는 QML에서 모델을 할당 할 수 있지만 델리게이트는 ScoreRecord의 속성을 볼 수 없습니다. 어딘가에 뭔가를 등록해야합니까? 도와주세요.

scorerecord.h

class ScoreRecord : public QObject 
{ 
    Q_OBJECT 

    Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) 
    Q_PROPERTY(QString date READ date WRITE setDate NOTIFY dateChanged) 
    Q_PROPERTY(QString score READ score WRITE setScore NOTIFY scoreChanged) 
public: 
    ScoreRecord(QObject *parent = 0); 
    ScoreRecord(const QString& n, const QString &d, const QString &s, QObject *parent = 0); 
    QString name() const; 
    void setName(const QString &str); 
    QString date() const; 
    void setDate(const QString &str); 
    QString score() const; 
    void setScore(const QString &str); 


signals: 
    void nameChanged(); 
    void dateChanged(); 
    void scoreChanged(); 

public slots: 

private: 
    QString m_name; 
    QString m_date; 
    QString m_score; 
}; 

scorehandler.h

class ScoreHandler : public QObject 
{ 
    Q_OBJECT 
private: 
    const char* SCORE_TABLE_FILENAME; 

    struct scoreRow { 
     char name[128]; 
     char date[32]; 
     char score[16]; 
    }; 


public: 
    explicit ScoreHandler(QObject *parent = 0); 
    QList<ScoreRecord *> scoreList; 

signals: 

public slots: 
    void SaveScore(const QString &name, const QString &date, const QString &score); 
    void LoadScore(); 
}; 

main.c를

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

    QGuiApplication app(argc, argv); 
    QtQuick2ApplicationViewer viewer; 

    ScoreHandler* scoreHandler = new ScoreHandler(); 
    QQmlContext* ctx = viewer.rootContext(); 
    ctx->setContextProperty("MyScoreModel", QVariant::fromValue(scoreHandler->scoreList)); 
    viewer.setMainQmlFile(QStringLiteral("qml/qmlListView/main.qml")); 

    viewer.showExpanded(); 

    return app.exec(); 
} 

QML 파일

import QtQuick 2.0 

Rectangle { 
    width: 360 
    height: 360 

    ListView { 
     width: 100; height: 100 
     anchors.fill: parent 

     model: MyScoreModel 
     delegate: Text { 
      text: name 
     } 
    } 
} 

그리고 제발 누군가가 나를 설명 할 수 있습니다, 왜 다음 코드는 작동합니까? 그 이유는 무엇입니까?

난 강력하게

ctx->setContextProperty("MyScoreModel", QVariant::fromValue(scoreHandler->scoreList)); 

주어진 예제에서 빈 현재 목록의 사본을 수행하고 scoreList을 수정할 때 업데이트되지 않습니다 있다고 생각

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

    QGuiApplication app(argc, argv); 
    QtQuick2ApplicationViewer viewer; 

    ScoreHandler* scoreHandler = new ScoreHandler(); 
    QList<QObject *> scoreList; 

    scoreList.append(new ScoreRecord("Jmeno1", "datum1", "score1")); 
    scoreList.append(new ScoreRecord("Jmeno2", "datum2", "score2")); 
    scoreList.append(new ScoreRecord("Jmeno3", "datum3", "score3")); 

    QQmlContext* ctx = viewer.rootContext(); 
    ctx->setContextProperty("MyScoreModel", QVariant::fromValue(scoreList)); 
    viewer.setMainQmlFile(QStringLiteral("qml/qmlListView/main.qml")); 

    viewer.showExpanded(); 

    return app.exec(); 
} 
+1

가 해결을, 내가 QList를 변경했다 scoreList; QList에 scoreList; QML에서 속성을 볼 수있게합니다. – user3032524

답변

0

을 main.c. Qt doc는 말한다 :

참고 : 뷰가 QList의 내용이 변경되었음을 알 수있는 방법이 없습니다. QList가 변경되면 QQmlContext :: setContextProperty()를 다시 호출하여 모델을 재설정해야합니다. data(...), rowCount()count 재산, roleNames() :

당신이 실제 데이터 모델이 필요하면

가 필요 재정의를 QAbstractListModel에서 파생 및 구현합니다.

마지막 샘플은 정적 목록을 컨텍스트 변수에 지정하기 때문에 작동합니다. JavaScript와 동일 :

[{name: Jmeno1, date: datum1, score: score1}, 
{name: Jmeno2, date: datum3, score: score2}, 
{name: Jmeno3, date: datum3, score: score3}] 
3

나는 더 깨끗한 방법이 있다고 생각합니다.

Q_PROPERTY(QQmlListProperty<ScoreRecord> scoreList READ scoreList) 

그리고 당신의 ScoreRecord 포인터를 보유 개인 변수 : 당신은 당신의 ScoreHandler에 속성 scoreList를 정의 할 필요가

QList _scoreRecords을;

// ScoreHandler.h 
QQmlListProperty<ScoreRecord> scoreList(); 

// ScoreHandler.cpp 
QQmlListProperty<ScoreRecord> ScoreHandler::scoreList() 
{ 
    return QQmlListProperty<ScoreRecord>(this, _scoreRecords); 
} 

당신은 다음 QML에서 액세스 할 수 있습니다

그런 다음 당신은 접근 방법을 구현해야합니다.

QtCreator에 대한 예가 있습니다.그것은 QML 확장이라고합니다 - 객체 및 목록 부동산 유형 예

0

누누 산토스의 대답은, 나는 또한 당신이해야 할 수있는 두 가지 중요한 수정을 가리키는 것이 좋다 : 예 QML 형식 시스템과 must be registered을 ScoreRecord

참고 :

qmlRegisterType<ScoreRecord>("com.mycompany.database", 1, 0, "ScoreRecord"); 및 ScoreRecord 네임 스페이스에있는 경우, you have to이 같은 속성을 정의

Q_PROPERTY(QQmlListProperty<myNamespace::ScoreRecord> scoreList READ scoreList) 
관련 문제