1

我正在尝试使用 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]
    ...
}

我只是没有让它工作:我不断回来[未定义]。我是在浪费时间,还是我错过了什么?

编辑: 我已经改变了一些事情来使用...的建议。以下是我更新的代码中的一些选择。

主.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
    ...
}

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

4

1 回答 1

0

这是很有可能的。关键是确保在 QDeclarativeView 上设置源之前注册 QML 类型并设置上下文属性。

这是一个工作示例 -

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

于 2013-10-21T21:36:49.557 回答