2013-11-25 35 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 
     } 
    } 
} 

請有人可以解釋我,爲什麼下面的代碼工作?是什麼原因?

的main.c

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 得分列表;進入QList scoreList;使其屬性在QML中可見。 – user3032524

回答

0

我堅信,

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

執行當前列表,這是在給定的例子空的副本中,當你修改scoreList沒有更新。 Qt doc說:

注:有沒有辦法讓視圖知道一個 的QList的內容發生了變化。如果QList更改,則需要通過再次調用QQmlContext :: setContextProperty()來重置 模型。

如果你需要真正的數據模型,從QAbstractListModel派生並實施必要的替代:data(...)rowCount()count財產,roleNames()

最後一個示例工作,因爲它將靜態列表分配給上下文變量。和JavaScript一樣:

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

我相信有一個更乾淨的方法。您需要定義您ScoreHandler屬性得分列表:

Q_PROPERTY(QQmlListProperty<ScoreRecord> scoreList READ scoreList) 

並保存你的ScoreRecord指針私有變量:

的QList _scoreRecords;

然後,你需要實現存取方法:

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

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

然後,您可以從QML訪問它。

QtCreator上有一個關於此的例子。它被稱爲擴展QML - 對象和列表屬性類型示例

0

努諾·桑托斯的回答是不錯的,我也想指出兩個重要的修改,您可能需要:

注意與QML類型的系統,如ScoreRecord must be registeredqmlRegisterType<ScoreRecord>("com.mycompany.database", 1, 0, "ScoreRecord");

並且如果ScoreRecord是命名空間中,限定you have to屬性是這樣的:

Q_PROPERTY(QQmlListProperty<myNamespace::ScoreRecord> scoreList READ scoreList)