Qml中的“无效属性赋值:..只读属性”

时间:2014-03-11 01:30:25

标签: qt qml

我正在尝试在Qml中使用list属性来获取底层C ++对象。我希望能够读写它。 QQmlListProperty的文档说只实现了READ函数,并用于读取编写对象。我收到错误消息:

  

无效的属性赋值:“string”是只读属性

当我尝试运行该应用时。以下是相关的源文件:

的main.cpp

#include <QtGui/QGuiApplication>
#include <QtQml>
#include "qtquick2applicationviewer.h"

#include "A.h"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    qmlRegisterType<A>("TestQmlComponents", 1, 0, "A");

    QtQuick2ApplicationViewer viewer;
    viewer.setMainQmlFile(QStringLiteral("qml/TestQml/main.qml"));
    viewer.showExpanded();

    return app.exec();
}

main.qml:

import QtQuick 2.0
import TestQmlComponents 1.0

Rectangle {
    width: 360
    height: 360

    A {
        id: a
        string: [
            "a", "b", "c"
        ]
    }

    Text {
        text: qsTr("Hello World")
        anchors.centerIn: parent
    }
    MouseArea {
        anchors.fill: parent
        onClicked: {
            Qt.quit();
        }
    }
}

A.H:

#ifndef A_H
#define A_H

#include <QObject>
#include <QList>
#include <QString>
#include <QtQml/QQmlListProperty>

class A : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QQmlListProperty<QString> string READ stringList)

public:
    explicit A(QObject *parent = 0);

    static void addString(QQmlListProperty<QString> *list, QString *str);
    void addString(QString *str);
    static int stringCount(QQmlListProperty<QString> *list);
    int stringCount() const;
    QQmlListProperty<QString> stringList();
    static QString *getString(QQmlListProperty<QString> *list, int ix);
    QString *getString(int ix);

private:
    QList<QString *> _string;
};

#endif // A_H

A.cpp

#include "A.h"

A::A(QObject *parent) :
    QObject(parent)
{
}

void A::addString(QQmlListProperty<QString> *list, QString *str)
{
    A *obj = qobject_cast<A *>(list->object);

    if (obj)
       obj->addString(str);
}

void A::addString(QString *str)
{
    _string << str;
}

int A::stringCount(QQmlListProperty<QString> *list)
{
    A *obj = qobject_cast<A *>(list->object);

    if (obj)
        return obj->stringCount();

    return 0;
}

QString *A::getString(int ix)
{
    return _string.at(ix);
}

QString *A::getString(QQmlListProperty<QString> *list, int ix)
{
    A *obj = qobject_cast<A *>(list->object);

    if (obj)
        return obj->getString(ix);

    return NULL;
}

int A::stringCount() const
{
    return _string.count();
}

QQmlListProperty<QString> A::stringList()
{
    return QQmlListProperty<QString>(this, NULL, addString, stringCount, getString, NULL);
}

知道我做错了吗?

1 个答案:

答案 0 :(得分:2)

QQmlListProperty只能用于QObject派生的对象指针列表。

由于QStringList作为数组类型透明地暴露给JavaScript,因此您可以通过两种方式直接公开此类属性:

  1. 作为Q_PROPERTY,需要注意修改是昂贵的,因为整个字符串列表被检索,然后被修改,然后被回写。对于大型列表,这很慢。

    Q_PROPERTY(QStringList strings READ strings WRITE setStrings NOTIFY stringsChanged)
    Q_SIGNAL void stringsChanged(const QStringList &);
    ...
    QStringList strings() const { return m_strings; }
    void setStrings(const QStringList & strings ) {
      m_strings = strings;
      emit stringsChanged(m_strings);
    }
    
  2. 作为从Q_INVOKABLE方法返回的引用:直接访问数据。

    Q_INVOKABLE QStringList & strings() { return m_strings; }