可以直接访问QDeclarativeListProperty而不是模型吗?

时间:2013-10-21 20:19:02

标签: qt qt4 qml qt4.8

我正在尝试使用QDeclarativeListProperty来管理参数列表,主要是为了在ListView中显示它们。但是,我还希望能够从QDeclarativeListProperty直接访问QML中的参数,以便我可以在不同的屏幕上显示/修改各个参数。

我的类叫做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
    ...
}

在这种情况下,我似乎仍然得到一个未定义的值。我现在正在尝试调试,以便我可以提供更多信息。

1 个答案:

答案 0 :(得分:0)

这是非常可能的。关键是要确保在QDeclarativeView上设置源代码之前注册QML类型并设置context属性。

这是一个有效的例子 -

<强> 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构造函数的文档。我在这个例子中使用的那个不是首选的,但对快速原型很有用。