admin管理员组

文章数量:1123887

I must create a QML "canvas" with items of different types. I was able to make it work on Qt 6.8, but my code must work also on Qt 5.15.

I am showing my entire "proof of concept" code, which includes more than the minimum - to allow you to understand that I really need the items, not their content.

The code below contains 2 small object types, with common QQuickItem parent, a class with a list containing a variety of items (that can change at run time, adding, removing and changing properties), a qml Repeater to show the items in the list, and a main to tie things together.

The line

property list<Item> myModel: Backend.model

gives error:

QQmlApplicationEngine failed to load component
qrc:/mainProof.qml:17:34: Syntax error

backend.h:

#ifndef BACKEND_H
#define BACKEND_H
#include <QQmlEngine>
#include <private/qquicktext_p.h>
#include <private/qquickrectangle_p.h>

class TextItem : public QQuickText
{
    Q_OBJECT
    QML_ELEMENT
    Q_PROPERTY(QString itemType MEMBER m_itemType NOTIFY itemTypeChanged)

public:
    TextItem() : QQuickText(Q_NULLPTR), m_itemType("TextItem") {
        setText("TextItem"); setPosition(QPointF(10, 15)); setSize(QSizeF(100, 20)); }
signals:
    void itemTypeChanged();
private:
    QString m_itemType;
};

class RectangleItem : public QQuickRectangle
{
    Q_OBJECT
    QML_ELEMENT
    Q_PROPERTY(QString itemType MEMBER m_itemType NOTIFY itemTypeChanged)

public:
    RectangleItem() : QQuickRectangle(Q_NULLPTR), m_itemType("RectangleItem") {
        setPosition(QPointF(40, 120)); setSize(QSizeF(100, 50)); setColor(Qt::red); }
signals:
    void itemTypeChanged();
private:
    QString m_itemType;
};

class Backend : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QList<QQuickItem *> model MEMBER m_model NOTIFY modelChanged)
    QML_ELEMENT
    QML_SINGLETON

public:
    explicit Backend(QObject *parent = nullptr) : QObject{parent} {
        m_model.append(new TextItem());
        m_model.append(new RectangleItem());
        RectangleItem *r = new RectangleItem(); r->setColor(Qt::green); r->setPosition(QPointF(180, 120)); m_model.append(r);
        TextItem *t = new TextItem(); t->setPosition(QPointF(40, 200)); t->setText("SecondTextItem"); m_model.append(t); 
    }
    virtual ~Backend() override {
        for (QQuickItem *item : m_model) delete item;
    }
signals:
    void modelChanged();
private:
    QList<QQuickItem *> m_model;
};
#endif // BACKEND_H

main.cpp:

#include "backend.h"
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

#define APP_URI "uri.dlitems"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    qmlRegisterSingletonType<Backend>(APP_URI, 1, 0, "Backend", [](QQmlEngine *, QJSEngine *) {
        return new Backend();
    });

    qmlRegisterType<TextItem>(APP_URI, 1, 0, "MyTextItem");
    qmlRegisterType<RectangleItem>(APP_URI, 1, 0, "MyRectangleItem");

    const QUrl url(QStringLiteral("qrc:/mainProof.qml"));
    QObject::connect(
        &engine,
        &QQmlApplicationEngine::objectCreated,
        &app,
        [url](QObject *obj, const QUrl &objUrl) {
            if (!obj && url == objUrl)
                QCoreApplication::exit(-1);
        },
        Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

mainProof.qml:

import QtQuick 2.12
import QtQuick.Window 2.1
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.0
import Qt.labs.qmlmodels 1.0
import uri.dlitems 1.0

ApplicationWindow {
    id: proofRoot

    visible: true
    width: 1024
    height: 545

    property list<Item> myModel: Backend.model   // Here I get error

    Rectangle {
        id: trouble
        anchors {
            top: parent.top
            left: parent.left
            right: parent.right
            bottom: parent.bottom
            margins: 20
        }

        Repeater {
            anchors.fill: parent
            anchors.margins: 20

            model: proofRoot.myModel

            delegate: DelegateChooser {
                id: chooser
                role: "itemType"

                DelegateChoice { roleValue: "TextItem"; MyTextItem {
                        x: model.x
                        y: model.y
                        height: model.height
                        width: model.width
                        color: model.color
                        text: model.text
                    }
                }
                DelegateChoice { roleValue: "RectangleItem"; MyRectangleItem {
                        x: model.x
                        y: model.y
                        height: model.height
                        width: model.width
                        color: model.color
                    }
                }
            }
        }
    }
}

Tried to make the line with error also:

property list<QtObject> myModel: Backend.model   // Qt 6 works, Qt 5 same syntax error

property list<var> myModel: Backend.model  // even Qt 6 fails to get the delegates (with the errors shown below); Qt 5 still syntax error

property var myModel: Backend.model        // Qt 5 accepts the list, but both Qt 5 and Qt 6 fail to get the delegates:

qrc:/mainProof.qml:45:25: Unable to assign [undefined] to QString
qrc:/mainProof.qml:44:25: Unable to assign [undefined] to QColor
qrc:/mainProof.qml:41:25: Unable to assign [undefined] to double
...

I also tried to use

Q_PROPERTY(QQmlListProperty<QQuickItem> model READ model NOTIFY modelChanged)

on the c++ side (with all the additional functions it entails); same behavior as with just QList

Nothing I try seems to make the Qt 5.15 work.

Any platform; Must work in Qt 5.15 (it works in Qt 6.8, probably any version above 6.4)

本文标签: cQt 515 QML Syntax error in listltItemgt (while Qt gt 64 works)Stack Overflow