Search code examples
c++qtcmakeqmlqt6

Qt 6: Prefer-field in CMake-generated qmldir prevents singletons from working


I have a simple manual qmldir that works fine:

singleton Constants 1.0 Constants.qml

However, now that I switched to qt_add_qml_module() and it generates the qmldir it does something like this:

module MyApplication
typeinfo MyApplication.qmltypes
prefer :/MyApplication/
Main 1.0 Main.qml
singleton Constants 1.0 Constants.qml

This seems to be correct, but now the application cannot find my singletons at runtime anymore:

TypeError: Cannot call method 'connect' of undefined

I debugged the issue and found out that if I remove prefer the singletons are found again. I don't understand the problem as the QML engine still can load the other QML-files, like Main.qml, despite the prefer-field.

What is going on and how to fix this?

I'm starting the application like this:

engine->load("qrc:/MyApplication/Main.qml");

I've tried to add all kinds of import paths, but that doesn't seem to fix it.

The CMake part:

set_source_files_properties(Constants.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE)

qt_add_qml_module(MyApplication
    URI MyApplication
    VERSION 1.0
    RESOURCE_PREFIX /
    QML_FILES
        Main.qml
        Constants.qml
)

Solution

  • You are just missing the import statement in your QML.

    import MyApplication
    

    Since you're using modules now, you need to make sure to import the module name to access the singleton. It is a little confusing because in your example it appears that your Main.qml is in the same module as the singleton, so it's understandable to think the import isn't necessary. I'm not sure why there is a difference between regular files and singletons when it comes to needing the import.