首页 > 解决方案 > QML:无法将 [未定义] 分配给

问题描述

我正在尝试将 Qt-Android 程序的界面从 QWidgets 重写为 QML。我之前从未使用过它,所以错误可能非常明显和愚蠢。

新界面基于ListView:

看起来像:

ListView
{
    id: listView
    x: 16
    y: 146
    width: 262
    height: 282
    model: myModel
    delegate: Item
    {
        x: 5
        width: 80
        height: 40
        Row
        {
            id: row1
            spacing: 10
            Text
            {
                width: 50
                text:model.modelData.getPassword
                font.bold: true
                anchors.verticalCenter: parent.verticalCenter
            }
            ProgressBar
            {
                value: model.modelData.getDifficulty
            }
        }
    }
}

main() 中的列表是这样填充的:

QList<QObject*> dataList;
dataList.append(new DataObject("Item 1", 50));
dataList.append(new DataObject("Item 2", 60));
dataList.append(new DataObject("Item 3", 70));
dataList.append(new DataObject("Item 4", 80));


QGuiApplication app(argc, argv);
qmlRegisterType<BackEnd>("tk.asciigames.backend", 1, 0, "BackEnd");

QQmlApplicationEngine engine;

engine.rootContext()->setContextProperty("myModel", QVariant::fromValue(dataList));

engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

return app.exec();

数据对象:

class DataObject : public QObject
{
    Q_OBJECT

    Q_PROPERTY(QString password         READ getPassword)
    Q_PROPERTY(unsigned int difficulty  READ getDifficulty)
public:
   DataObject(QString _pass, unsigned int _difficulty)
{
    difficulty = _difficulty;
    password = _pass;
}

QString getPassword()
{
    return password;
}

unsigned int getDifficulty()
{
    return difficulty;
}

private:
unsigned int    difficulty;
QString         password;

};

运行 QML 时确实显示 4 行(如预期)但没有数据。日志有这样的错误:

qrc:/main.qml:118:26: Unable to assign [undefined] to QString
qrc:/main.qml:124:28: Unable to assign [undefined] to double

这些错误对应于 QML 行:

text:model.modelData.getPassword
value: model.modelData.getDifficulty

所以看起来 QML 获取了数组但无法从中获取数据。

有人可以帮我找出错误吗?

标签: qtqml

解决方案


当您声明 Q_PROPERTY 时,您定义了一个名称和一个 getter 函数。c++ 使用 getter 函数来获取属性的实际值,但 QML 引擎对此一无所知;它只知道属性名称(password在本例中)

Q_PROPERTY(QString password READ getPassword)

因此,在您的 QML 文件中,更改行

text:model.modelData.getPassword
value: model.modelData.getDifficulty

text:model.modelData.password
value: model.modelData.difficulty

你应该很高兴。

请注意,您还可以使用缩短的语法来访问属性

value: model.modelData.difficulty // OK
value: model.difficulty // OK
value: modelData.difficulty // OK
value: difficulty // Still OK
value: model.model.model.model.model.modelData.difficulty // OK, but don't do that

您可能还想将 Q_PROPERTY 标记为 CONSTANT,以消除警告QQmlExpression: Expression qrc:/main.qml:25:20 depends on non-NOTIFYable properties:

Q_PROPERTY(QString password READ getPassword CONSTANT)

推荐阅读