2013-10-21 89 views
1

我想使用QDeclarativeListProperty來管理參數列表,主要是爲了在ListView中顯示它們的目的。但是,我也希望能夠直接從QDeclarativeListProperty訪問QML中的參數,以便我可以在不同屏幕上顯示/修改各個參數。是否可以直接訪問QDeclarativeListProperty,而不是作爲模型?

我的類叫做ParameterClass,爲此,我創建了一個的QList:

class SystemData : public QObject 
{ 
    Q_OBJECT 
    Q_PROPERTY(QDeclarativeListProperty<ParameterClass> parameters READ parameters CONSTANT) 
    QDeclarativeListProperty<ParameterClass> parameters(); 

... 

    QList<ParameterClass *> m_parameterList; 
} 

我還註冊了ParameterClass類,並建立了我的SystemData的實例作爲屬性,這是我所知道的是必要。現在

m_context->setContextProperty("SystemData", m_pSystemData); 
qmlRegisterType<ParameterClass>(); 

,我想內QML做的是這樣的:

Rectangle { 
    id: frame 
    property variant parameter: SystemData.parameters[5] 
    ... 
} 

我只是沒有得到它的工作:我不斷收到回[未定義]。我在浪費時間,還是在想念什麼?

編輯: 我已經改變了使用...的建議。以下是我的更新代碼中的一些選擇。

main.cpp中:

#include <QApplication> 
#include <QSplashScreen> 
#include <QLocale> 
#include <QLibraryInfo> 
#include <QDeclarativeView> 
#include <QDeclarativeContext> 
#include <QDeclarativeEngine> 
#include <QObject> 
#include <QDeclarativeListProperty> 

#include "systemdata.h" 
#include "parameterclass.h" 

static const QString contentPath = "qrc:/qml/qml/pk_ui/"; 
static const QString filename(contentPath + "main.qml"); 

int main(int argc, char *argv[]) 
{ 
    QApplication app(argc, argv); 
    QDeclarativeView mainView; 
    SystemData* systemData = SystemData::getInstance(); 

    QThread thread; 
    UpdateWorker updateWorker; 
    QObject::connect((const QObject*)systemData, SIGNAL(startWork()), 
        (const QObject*)&updateWorker, SLOT(doWork())); 
    updateWorker.moveToThread(&thread); 
    thread.start(); 
    systemData->startUpdates(); 

    QFont defaultFont; 
    defaultFont.setFamily("Sans Serif"); 
    QApplication::setFont(defaultFont); 

    // Register types to be available in QML 
    qmlRegisterType<ParameterClass>(); 
    qmlRegisterUncreatableType<SystemEnum>("SystemEnums", 1, 0, "SystemEnum", QString()); 

    mainView.engine()->rootContext()->setContextProperty("SystemData", systemData); 

    // Set view optimizations not already done for QDeclarativeView 
    mainView.setResizeMode(QDeclarativeView::SizeRootObjectToView); 
    mainView.setAttribute(Qt::WA_OpaquePaintEvent); 
    mainView.setAttribute(Qt::WA_NoSystemBackground); 

    mainView.setSource(QUrl(filename)); 
    mainView.show(); 

    return app.exec(); 
} 

的ParameterClass看起來是這樣的:

class ParameterClass : public QObject 
{ 
    Q_OBJECT 

    Q_PROPERTY(int type READ get_type NOTIFY typeChanged) 
    Q_PROPERTY(bool enabled READ get_ParameterEnabled WRITE set_ParameterEnabled NOTIFY enabledChanged) 
    Q_PROPERTY(int groupID READ get_GroupID WRITE set_GroupID NOTIFY groupIDChanged) 
    Q_PROPERTY(int unitID READ get_UnitID WRITE set_UnitID NOTIFY unitIDChanged) 
    Q_PROPERTY(int securityLevel READ get_SecurityLevel WRITE set_SecurityLevel NOTIFY securityLevelChanged) 
    Q_PROPERTY(QString parameterName READ get_ParameterName NOTIFY parameterNameChanged) 
    Q_PROPERTY(QString shortDescription READ get_ShortDescription NOTIFY shortDescriptionChanged) 
    Q_PROPERTY(int currentValue READ get_CV WRITE set_valueptrvalue NOTIFY currentValueChanged) 
    Q_PROPERTY(int lowerBound READ get_LB NOTIFY lowerBoundChanged) 
    Q_PROPERTY(int upperBound READ get_UB NOTIFY upperBoundChanged) 

public: 
    struct ValueTypes 
    { 
     enum 
     { 
      IntegerType, 
      StringType, 
      StringListType 
     }; 
    }; 


    ParameterClass(QObject *parent = 0); 
    int get_type(); 
    bool get_ParameterEnabled(); 
    int get_GroupID(); 
    int get_UnitID(); 
    int get_SecurityLevel(); 
    QString get_ParameterName(); 
    QString get_ShortDescription(); 
    int get_CV() { return *CurrentValuePtr; } 
    int get_LB() { return *LowerBoundPtr; } 
    int get_UB() { return *UpperBoundPtr; } 

    void set_ParameterEnabled(bool InParameterEnabled); 
    void set_GroupID(int InGroupID); 
    void set_UnitID(int InUnitID); 
    void set_SecurityLevel(int InSecurityLevel); 

signals: 
    void typeChanged(); 
    void enabledChanged(); 
    void groupIDChanged(); 
    void unitIDChanged(); 
    void securityLevelChanged(); 
    void parameterNameChanged(); 
    void shortDescriptionChanged(); 

private: 
    int type; 
    bool ParameterEnabled; 
    int GroupID; 
    int UnitID; 
    int SecruityLevel; 
    QString ParameterName; 
    QString ShortDescription; 
    int * CurrentValuePtr; 
    int * LowerBoundPtr; 
    int * UpperBoundPtr; 
}; 

我的QML文件:

Rectangle { 
    id: frame 
    property int val: SystemData.parameters[4].currentValue 
    ... 
} 

它看起來像我仍然得到一個未定義的VA在這種情況下。我現在正在嘗試調試,以便我可以提供更多信息。

回答

0

這是非常有可能的。關鍵是確保您註冊QML類型並設置上下文屬性,然後再在QDeclarativeView上設置源。

這裏有一個工作的例子 -

main.cpp中:

#include <QApplication> 
#include <QtDeclarative> 

class MyPropertyObject : public QObject { 
    Q_OBJECT 
    Q_PROPERTY(int value READ value CONSTANT) 

public: 
    MyPropertyObject(int value = -1) : m_value(value) { } 

    int value() const { 
     return m_value; 
    } 

private: 
    int m_value; 
}; 

class MyObject : public QObject { 
    Q_OBJECT 
    Q_PROPERTY(QDeclarativeListProperty<MyPropertyObject> props READ props CONSTANT) 

public: 

    MyObject() { 
     m_props.append(new MyPropertyObject(55)); 
     m_props.append(new MyPropertyObject(44)); 
     m_props.append(new MyPropertyObject(33)); 
    } 

    QDeclarativeListProperty<MyPropertyObject> props() { 
     return QDeclarativeListProperty<MyPropertyObject>(this, m_props); 
    } 

private: 
    QList<MyPropertyObject *> m_props; 
}; 

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

    QDeclarativeView view; 
    view.engine()->rootContext()->setContextProperty(QLatin1String("tester"), new MyObject); 
    qmlRegisterType<MyPropertyObject>(); 
    view.setSource(QUrl("qrc:///qml/main.qml")); 
    view.setResizeMode(QDeclarativeView::SizeRootObjectToView); 
    view.resize(300, 300); 
    view.show(); 

    return a.exec(); 
} 

#include "main.moc" 

main.qml:

import QtQuick 1.1 

Rectangle { 
    property variant foo: tester.props[2].value 

    Text { 
     anchors.centerIn: parent 
     text: parent.foo 
    } 
} 

注:閱讀文檔的QDeclarativeListProperty構造。我在這個例子中使用的不是首選的,但是對於快速原型是很好的。

+0

我已經移動了很多東西,將所有代碼從QDeclarativeView的包裝類中移出,並移入我的main.cpp中。通過這種方式,我可以保證我在爲視圖設置源之前註冊了所有類型,並且仍然沒有定義我的對象。我將更新上面的代碼,以瞭解我現在擁有的內容。 – ErikZane

+0

而不是有一個parameterChanged信號,更改該屬性像我的常量。 – ksimons

+0

我在編輯之後不久就做出了更改。現在我的代碼編譯並運行時沒有報告問題,但是我仍然得到未定義或0而不是我期望的值。調試顯示我的get_CV方法正在被調用,但我不確定實際到達QML的值。爲了記錄,調試QML是單調乏味的。 – ErikZane

相關問題