1

I have spent days researching and trying to figure this out, it should just work - but does not.

I am attempting to create and use a simple QML object as a single source of setting for my project.

As a test I have created a new Qt 6.7.3 QML project, and I added a new .qml file "TestQmlObj.qml" with a few properties.

Intellisense works, but I consistently get Unable to assign [undefined] to errors when run.

TestQmlObj.qml

pragma Singleton
import QtQuick

QtObject {

    readonly property color primaryColor: "red"
    readonly property color secondaryColor: "#FFC107"
    readonly property color backgroundColor: "#FFFFFF"

    readonly property font mainfont: Qt.font({
        family: "Arial",
        pointSize: 12,
        weight: Font.Normal
    })

    readonly property font headerFont: Qt.font({
        family: "Arial",
        pointSize: 16,
        weight: Font.Bold
    })
}

I then tried to use these properties in the Main.qml file.

Main.qml

import QtQuick

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    Rectangle {
        anchors.fill: parent
        //color: "red"
        color: TestQmlObj.primaryColor
        //color: TestQmlObj.backgroundColor

        Text {
            text: qsTr("text")
            font: TestQmlObj.headerFont
        }
    }
}

I have tried all kinds of suggested changes but in all cases I receive the following error and the color does not change.

qrc:/qt/qml/QmlObjTypes/Main.qml:13:9: Unable to assign [undefined] to QColor

CMakeLists.txt

cmake_minimum_required(VERSION 3.16)

project(QmlObjTypes VERSION 0.1 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt6 REQUIRED COMPONENTS Quick)

qt_standard_project_setup(REQUIRES 6.5)

qt_add_executable(appQmlObjTypes
    main.cpp
)

qt_add_qml_module(appQmlObjTypes
    URI QmlObjTypes
    VERSION 1.0
    QML_FILES
        Main.qml
        TestQmlObj.qml
)

# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an
# explicit, fixed bundle identifier manually though.
set_target_properties(appQmlObjTypes PROPERTIES
#    MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appQmlObjTypes
    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
    MACOSX_BUNDLE TRUE
    WIN32_EXECUTABLE TRUE
)

target_link_libraries(appQmlObjTypes
    PRIVATE Qt6::Quick
)

include(GNUInstallDirs)
install(TARGETS appQmlObjTypes
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
3
  • 1
    If you want your TestQmlObj to be a singleton, you need to specify that in your CMake file: set_source_files_property(TestQmlObj.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE) Commented Jan 8 at 13:56
  • Thank you JarMan, that worked. I have 2 follow up questions: 1) How would I do this when not creating a singleton? When I comment out the pragma Singleton the same errors return. 2) I'm new to QML and searched for days for a solution. How should I have searched to find set_source_files_properties when all I had was the "Unable to assign [undefined] to" error? Commented Jan 8 at 14:21
  • It's not something you can understand only from the error message. If you hadn't provided the source code, then no one would know what the problem is. The error simply indicates that TestQmlObj.primaryColor is undefined. And by examining the code, you should realize that TestQmlObj should be a singleton or an attached property, Commented Jan 8 at 16:22

1 Answer 1

2

The reason you are unable to access TestQmlObj is because you are attempting to use it as a singleton, but you have not finished declaring it as such. The docs describe two methods for declaring singletons:

  1. If you define your singleton from QML, you must label it with pragma Singleton AND you must add an entry into the qmldir file of your module. The best way to do that is by setting the source property in your CMakeLists.txt file.
set_source_files_property(TestQmlObj.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE)
  1. The other way is to define your singleton object from C++ using the QML_SINGLETON macro.
class MySingleton : public QObject
{
    Q_OBJECT
    QML_SINGLETON
    QML_ELEMENT
public:
    MySingleton(QObject *parent = nullptr) : QObject(parent) {
        // ...
    }
};

Since you have defined your object in QML, you should use option 1 and make sure you update your CMakeLists.txt file.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for another helpful response. I was unable to get set_source_files_property to work, but set_source_files_properties did work. Thanks again. Initially having only, the "Unable to assign [undefined] to" error to work with I had no idea where the problem was coming from. What surprises me is that not one of the examples if found searching included this change in the CMakeLists file. Could you recommend any books, web sites or training classes that are both current and very detailed in using QML, Qt and CMakeLists? Thank you again.
Editing the qmldir file is the important part. The CMake function does that automatically for you and is new with Qt6, I believe. (I might be wrong on that.) A lot of the examples you will find were originally written for Qt5 but they should at least manually edit the qmldir file.
Yes. I tried to edit the qmldir file but my edits were being overwritten by the CMakeLists not having the set_source_files_properties line that you provided. I was pretty much convinced that my code was right but until this discussion had no idea where to look next. Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.