Home > Back-end >  QML: Failure accessing properties with error "Unable to assign [undefined] to "
QML: Failure accessing properties with error "Unable to assign [undefined] to "

Time:08-11

I have this simple QML files:

qml/Constants.qml:

pragma Singleton
import QtQuick 2.15

QtObject {
    readonly property int width: 1920
    readonly property int height: 1080

    readonly property color bgColor: "#c2c2c2"
}

qml/MainMenu.qml:

import QtQuick 2.15
import QtQuick.Controls 2.15

Rectangle {
    id: mainMenu
    width: Constants.width
    height: Constants.height
    visible: true
    color: Constants.bgColor
    border.color: "#ffffff"
    clip: false
}

and the main window in qml/main.qml:

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.15

Window {
    id: root
    width: Constants.width
    height: Constants.height

    visible: true

    StackView {
        id: stack
        anchors.fill: parent
        initialItem: MainMenu {}
    }
}

I build the resources using this resources.qrc with rcc:

<!DOCTYPE RCC><RCC version="1.0">
        <qresource prefix="/mbh">
                <file alias="Constants.qml">qml/Constants.qml</file>
                <file alias="main.qml">qml/main.qml</file>
                <file alias="MainMenu.qml">qml/MainMenu.qml</file>
        </qresource>
</RCC>

And execute the main.qml using a simple main.cpp that simply load and execute qml/main.qml. During execution I have these errors:

qrc:/mbh/main.qml:8:5: Unable to assign [undefined] to int
qrc:/mbh/main.qml:7:5: Unable to assign [undefined] to int
qrc:/mbh/MainMenu.qml:9:5: Unable to assign [undefined] to QColor

Why main.qml is not able to get Constants.width and Constants.height, but MainMenu.qml is (apparently) able to obtain these 2 values? And why MainMenu.qml is not able to obtain Constants.bgColor?

NOTE: Qt version is 5.15.2

Thanks

CodePudding user response:

As noted by JarMan the singleton shall be correctly initialized.

It is enough to create a qmldir file (there is no need to create a module), qml/qmldir:

singleton Constants 1.0 Constants.qml

And add the qmldir file to the list of resources in resources.qrc:

<!DOCTYPE RCC><RCC version="1.0">
        <qresource prefix="/mbh">
                <file alias="qmldir">qml/qmldir</file>
...

CodePudding user response:

Alternative solution is

  1. Add qmlRegisterSingletonType() to main.cpp:
    qmlRegisterSingletonType(
        QUrl("qrc:/your/prefix/to/Constants.qml"),
        "ConstantsModule",
        1, 0,
        "Constants");
    
  2. Do import ConstantsModule 1.0 anywhere you use Constants.

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>

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

    // !!! THIS LINE, the rest are default Qt template lines
    // WARNING use your own qrc prefix for Constants.qml
    qmlRegisterSingletonType(
                QUrl("qrc:/stackoverflow4/Constants.qml"),
                "ConstantsModule",
                1, 0,
                "Constants");

    QQmlApplicationEngine engine;
    const QUrl url(u"qrc:/stackoverflow4/main.qml"_qs);
    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();
}

main.qml

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.15

import ConstantsModule 1.0 // !!! THIS LINE

Window {
    id: root
    width: Constants.width
    height: Constants.height

    visible: true

    StackView {
        id: stack
        anchors.fill: parent
        initialItem: MainMenu{}
    }
}

Constants.qml

pragma Singleton
import QtQuick 2.15

QtObject {
    readonly property int width: 1920
    readonly property int height: 1080
    readonly property color bgColor: "#c2c2c2"
}

MainMenu.qml

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.15

import ConstantsModule 1.0 // !!! THIS LINE

Rectangle {
    id: mainMenu
    width: Constants.width
    height: Constants.height
    visible: true
    color: Constants.bgColor
    border.color: "#ffffff"
    clip: false
}
  • Related