How to create QML singleton
-
wrote on 23 Jan 2024, 21:57 last edited by
I am sorry to ask this question but after reading all documentation and trying to google it I am still not able to create and use singleton on QML :-(
I have following file:
qml/EPGColors.qml:
pragma Singleton import QtQuick QtObject { readonly property color pastProgColor: "#e4e4e4" }
I have added it to cmakefile:
set_source_files_properties(qml/EPGColors.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE) qt6_add_qml_module(${TARGET} URI ProgrammeGuide QML_FILES qml/epg.qml qml/EPGItem.qml qml/EPGSwitch.qml qml/EPGTabBar.qml qml/EPGTabButton.qml qml/EPGColors.qml NO_RESOURCE_TARGET_PATH VERSION 1.0 )
Now, I am trying to use it in qml/EPGItem.qml:
property color myColor: EPGColors.pastProgColor
And I get this error:
qrc:/qml/EPGItem.qml:40:5: Unable to assign [undefined] to QColor
It seems to be aligned with documentation: https://doc.qt.io/qt-6/qt-target-qml-sources.html#source-file-properties
What am I doing wrong?
Thanks!
-
I am sorry to ask this question but after reading all documentation and trying to google it I am still not able to create and use singleton on QML :-(
I have following file:
qml/EPGColors.qml:
pragma Singleton import QtQuick QtObject { readonly property color pastProgColor: "#e4e4e4" }
I have added it to cmakefile:
set_source_files_properties(qml/EPGColors.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE) qt6_add_qml_module(${TARGET} URI ProgrammeGuide QML_FILES qml/epg.qml qml/EPGItem.qml qml/EPGSwitch.qml qml/EPGTabBar.qml qml/EPGTabButton.qml qml/EPGColors.qml NO_RESOURCE_TARGET_PATH VERSION 1.0 )
Now, I am trying to use it in qml/EPGItem.qml:
property color myColor: EPGColors.pastProgColor
And I get this error:
qrc:/qml/EPGItem.qml:40:5: Unable to assign [undefined] to QColor
It seems to be aligned with documentation: https://doc.qt.io/qt-6/qt-target-qml-sources.html#source-file-properties
What am I doing wrong?
Thanks!
What's in EPGItem.qml? Do you import your module there?
-
wrote on 24 Jan 2024, 17:56 last edited by
I have deleted build folder and now there is
singleton EPGColors 1.0 qml/EPGColors.qml
in qmldir file.
I have added import to EPGItem.qml:
import QtQuick import Qt5Compat.GraphicalEffects // required for Qt < 6.5 // import QtQuick.Effects // not available in Qt < 6.5 import ProgrammeGuide Item { id: progItem // ... property color pastProgColor: EPGColors.pastProgColor // ... }
And now I get this message that is even more confusing:
qrc:/qml/EPGItem.qml:42: TypeError: EPGColors was a singleton at compile time, but is not a singleton anymore.
-
wrote on 24 Jan 2024, 18:30 last edited by
I do not know how to attach file, so this is cope and paste of minimal example:
CMakeList.txt
cmake_minimum_required(VERSION 3.16) project(SingletonTest VERSION 0.1 LANGUAGES CXX) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Qt6 6.4 REQUIRED COMPONENTS Quick) qt_standard_project_setup() qt_add_executable(appSingletonTest main.cpp ) set_source_files_properties(qml/Colors.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE) qt_add_qml_module(appSingletonTest URI SingletonTest VERSION 1.0 QML_FILES qml/main.qml QML_FILES qml/Colors.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(appSingletonTest PROPERTIES # MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appSingletonTest 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(appSingletonTest PRIVATE Qt6::Quick ) include(GNUInstallDirs) install(TARGETS appSingletonTest BUNDLE DESTINATION . LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} )
main.cpp:
#include <QGuiApplication> #include <QQmlApplicationEngine> int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; const QUrl url(u"qrc:/SingletonTest/qml/main.qml"_qs); QObject::connect( &engine, &QQmlApplicationEngine::objectCreationFailed, &app, []() { QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url); return app.exec(); }
qml/main.qml:
import QtQuick import SingletonTest Window { width: 640 height: 480 visible: true title: qsTr("Hello World") Rectangle { width: parent.width/2 height: parent.height/2 anchors.centerIn: parent color: Colors.myColor } }
qml/Colors.qml:
pragma Singleton import QtQuick QtObject { id: colors readonly property color myColor: "red" }
When I run it I get this message:
qrc:/SingletonTest/qml/main.qml:14: TypeError: Colors was a singleton at compile time, but is not a singleton anymore.
-
I do not know how to attach file, so this is cope and paste of minimal example:
CMakeList.txt
cmake_minimum_required(VERSION 3.16) project(SingletonTest VERSION 0.1 LANGUAGES CXX) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Qt6 6.4 REQUIRED COMPONENTS Quick) qt_standard_project_setup() qt_add_executable(appSingletonTest main.cpp ) set_source_files_properties(qml/Colors.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE) qt_add_qml_module(appSingletonTest URI SingletonTest VERSION 1.0 QML_FILES qml/main.qml QML_FILES qml/Colors.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(appSingletonTest PROPERTIES # MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appSingletonTest 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(appSingletonTest PRIVATE Qt6::Quick ) include(GNUInstallDirs) install(TARGETS appSingletonTest BUNDLE DESTINATION . LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} )
main.cpp:
#include <QGuiApplication> #include <QQmlApplicationEngine> int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; const QUrl url(u"qrc:/SingletonTest/qml/main.qml"_qs); QObject::connect( &engine, &QQmlApplicationEngine::objectCreationFailed, &app, []() { QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url); return app.exec(); }
qml/main.qml:
import QtQuick import SingletonTest Window { width: 640 height: 480 visible: true title: qsTr("Hello World") Rectangle { width: parent.width/2 height: parent.height/2 anchors.centerIn: parent color: Colors.myColor } }
qml/Colors.qml:
pragma Singleton import QtQuick QtObject { id: colors readonly property color myColor: "red" }
When I run it I get this message:
qrc:/SingletonTest/qml/main.qml:14: TypeError: Colors was a singleton at compile time, but is not a singleton anymore.
What if you put the QML files in the root folder of the project?
Colors.qml
instead ofqml/Colors.qml
Also I'd remove the second
QML_FILES
inqt_add_qml_module
-
What if you put the QML files in the root folder of the project?
Colors.qml
instead ofqml/Colors.qml
Also I'd remove the second
QML_FILES
inqt_add_qml_module
wrote on 24 Jan 2024, 19:04 last edited byIf I move Colors.qml to root folder and change CMakeList.txt accordingly:
set_source_files_properties(Colors.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE) qt_add_qml_module(appSingletonTest URI SingletonTest VERSION 1.0 QML_FILES qml/main.qml Colors.qml )
I get this error when I run the application:
qrc:/SingletonTest/qml/main.qml:14: ReferenceError: Colors is not defined
-
If I move Colors.qml to root folder and change CMakeList.txt accordingly:
set_source_files_properties(Colors.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE) qt_add_qml_module(appSingletonTest URI SingletonTest VERSION 1.0 QML_FILES qml/main.qml Colors.qml )
I get this error when I run the application:
qrc:/SingletonTest/qml/main.qml:14: ReferenceError: Colors is not defined
wrote on 24 Jan 2024, 19:20 last edited by KejPiIt seems all QML files must be in root folder including some other custom components files.
If I do this, it works:
set_source_files_properties(Colors.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE) qt_add_qml_module(appSingletonTest URI SingletonTest VERSION 1.0 QML_FILES main.qml Colors.qml SomeComponent.qml )
This strange, so far I put all my QML files to dedicated folder (qml/) to separate it from C++ and everything was working (see my first example code) - only the singleton causes some problem.
I could consider this as workaround but I do not like it since I will mix QML with C++ and it will be a mess :-(
EDIT: It seems that this construction works too:
set_source_files_properties(qmlfiles/Colors.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE) set_source_files_properties(qmlfiles/main.qml PROPERTIES QT_RESOURCE_ALIAS main.qml) set_source_files_properties(qmlfiles/Colors.qml PROPERTIES QT_RESOURCE_ALIAS Colors.qml) set_source_files_properties(qmlfiles/SomeComponent.qml PROPERTIES QT_RESOURCE_ALIAS SomeComponent.qml) qt_add_qml_module(appSingletonTest URI SingletonTest VERSION 1.0 QML_FILES qmlfiles/main.qml qmlfiles/Colors.qml qmlfiles/SomeComponent.qml )
-
It seems all QML files must be in root folder including some other custom components files.
If I do this, it works:
set_source_files_properties(Colors.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE) qt_add_qml_module(appSingletonTest URI SingletonTest VERSION 1.0 QML_FILES main.qml Colors.qml SomeComponent.qml )
This strange, so far I put all my QML files to dedicated folder (qml/) to separate it from C++ and everything was working (see my first example code) - only the singleton causes some problem.
I could consider this as workaround but I do not like it since I will mix QML with C++ and it will be a mess :-(
EDIT: It seems that this construction works too:
set_source_files_properties(qmlfiles/Colors.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE) set_source_files_properties(qmlfiles/main.qml PROPERTIES QT_RESOURCE_ALIAS main.qml) set_source_files_properties(qmlfiles/Colors.qml PROPERTIES QT_RESOURCE_ALIAS Colors.qml) set_source_files_properties(qmlfiles/SomeComponent.qml PROPERTIES QT_RESOURCE_ALIAS SomeComponent.qml) qt_add_qml_module(appSingletonTest URI SingletonTest VERSION 1.0 QML_FILES qmlfiles/main.qml qmlfiles/Colors.qml qmlfiles/SomeComponent.qml )
@KejPi open a bugreport because QML SINGLETON doesn't work if not in root folder
-
@KejPi open a bugreport because QML SINGLETON doesn't work if not in root folder
wrote on 26 Jan 2024, 14:57 last edited byI do not know why the one from the post does not work, but singletons from subdirectories work.
I used here
-
I do not know why the one from the post does not work, but singletons from subdirectories work.
I used here
@Mesrine aaah - good to know. just porting my apps from QMake to CMake. next step will be to modernize my apps, where I'll need QML SINGLETONS, too
-
It seems all QML files must be in root folder including some other custom components files.
If I do this, it works:
set_source_files_properties(Colors.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE) qt_add_qml_module(appSingletonTest URI SingletonTest VERSION 1.0 QML_FILES main.qml Colors.qml SomeComponent.qml )
This strange, so far I put all my QML files to dedicated folder (qml/) to separate it from C++ and everything was working (see my first example code) - only the singleton causes some problem.
I could consider this as workaround but I do not like it since I will mix QML with C++ and it will be a mess :-(
EDIT: It seems that this construction works too:
set_source_files_properties(qmlfiles/Colors.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE) set_source_files_properties(qmlfiles/main.qml PROPERTIES QT_RESOURCE_ALIAS main.qml) set_source_files_properties(qmlfiles/Colors.qml PROPERTIES QT_RESOURCE_ALIAS Colors.qml) set_source_files_properties(qmlfiles/SomeComponent.qml PROPERTIES QT_RESOURCE_ALIAS SomeComponent.qml) qt_add_qml_module(appSingletonTest URI SingletonTest VERSION 1.0 QML_FILES qmlfiles/main.qml qmlfiles/Colors.qml qmlfiles/SomeComponent.qml )
wrote on 29 Jan 2024, 10:32 last edited by JansonThis post is deleted! -
wrote on 29 Jan 2024, 21:11 last edited by
I have a small example project that clearly shows it does not work as expected. I can share it but I do not know how to do it here. Maybe I did something wrong - I have juste created project in QtCreator and moved all QML files in subdirectory.
-
I do not know why the one from the post does not work, but singletons from subdirectories work.
I used here
-
I do not know how to attach file, so this is cope and paste of minimal example:
CMakeList.txt
cmake_minimum_required(VERSION 3.16) project(SingletonTest VERSION 0.1 LANGUAGES CXX) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Qt6 6.4 REQUIRED COMPONENTS Quick) qt_standard_project_setup() qt_add_executable(appSingletonTest main.cpp ) set_source_files_properties(qml/Colors.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE) qt_add_qml_module(appSingletonTest URI SingletonTest VERSION 1.0 QML_FILES qml/main.qml QML_FILES qml/Colors.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(appSingletonTest PROPERTIES # MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appSingletonTest 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(appSingletonTest PRIVATE Qt6::Quick ) include(GNUInstallDirs) install(TARGETS appSingletonTest BUNDLE DESTINATION . LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} )
main.cpp:
#include <QGuiApplication> #include <QQmlApplicationEngine> int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; const QUrl url(u"qrc:/SingletonTest/qml/main.qml"_qs); QObject::connect( &engine, &QQmlApplicationEngine::objectCreationFailed, &app, []() { QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url); return app.exec(); }
qml/main.qml:
import QtQuick import SingletonTest Window { width: 640 height: 480 visible: true title: qsTr("Hello World") Rectangle { width: parent.width/2 height: parent.height/2 anchors.centerIn: parent color: Colors.myColor } }
qml/Colors.qml:
pragma Singleton import QtQuick QtObject { id: colors readonly property color myColor: "red" }
When I run it I get this message:
qrc:/SingletonTest/qml/main.qml:14: TypeError: Colors was a singleton at compile time, but is not a singleton anymore.
wrote on 30 Jan 2024, 07:41 last edited by MesrineI have used your minimal example and works ok :) .
The only thing I changed was that instead of
CMakeList.txt
i namedCMakeLists.txt
.I have tested it with qt(shared libraries) 6.5,6.6,6.7 in Linux.
Make sure you are using the correct
CMakeLists.txt
.
And let us know your platform and Qt version. -
wrote on 30 Jan 2024, 18:35 last edited by KejPi
Yes, it was only typo, I use the CMakeLists.txt created by Qt Creator.
I am running it on MacOS 14.2, Qt version 6.5.3 -
Yes, it was only typo, I use the CMakeLists.txt created by Qt Creator.
I am running it on MacOS 14.2, Qt version 6.5.3wrote on 31 Jan 2024, 06:53 last edited by@KejPi
Do you run the application that is on the build directory or the installed one?Try putting
set_source_files_properties(qml/Colors.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE)
before
qt_add_executable(appSingletonTest main.cpp )
in your minimal example.
If that does not work try removing some macos properties in the CMakeLists.txt.
If nothing works I would say you can open a bug as suggested by @ekkescorner -
@KejPi
Do you run the application that is on the build directory or the installed one?Try putting
set_source_files_properties(qml/Colors.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE)
before
qt_add_executable(appSingletonTest main.cpp )
in your minimal example.
If that does not work try removing some macos properties in the CMakeLists.txt.
If nothing works I would say you can open a bug as suggested by @ekkescornerwrote on 31 Jan 2024, 18:51 last edited by KejPi@Mesrine I run the application directly from Qt Creator after building it.
Movingset_source_files_properties
did not help, the problem is the same.Bug report created https://bugreports.qt.io/browse/QTBUG-121758
1/17