QML singleton instantiation issue
-
I have a simple Qt Quick project whose tree looks like this:
main.qml actions/ AppActions.qml qmldir stores/ UserStore.qml qmldirBoth
AppActionsandUserStoreare marked withpragma Singletonand are marked as singletons in their correspondingqmldirfiles. InAppActionsa signal is declared, and inUserStorea connection is made to that signal. This signal is emitted upon the receipt ofonClickedin aButtoninmain.qml.At first glance, the signal is not received by
UserStorebecauseUserStoredoes not exist. Only upon adding a no-op call ofUserStore;inmain.qmlis the UserStore created and the signal properly received. From what I understand, the singleton types ought to be instantiated given the presence of theqmldirfiles.Here are the relevant source files:
AppActions.qml:pragma Singleton import QtQuick 2.12 Item { signal login(); }UserStore.qml:pragma Singleton import QtQuick 2.12 import "../actions" Item { Connections { target: AppActions onLogin: { console.log("Logged in!"); } } }main.qml:import QtQuick 2.0 import QtQuick.Layouts 1.3 import QtQuick.Controls 2.5 import QtQuick.Controls.Styles 1.4 import QtQuick.Window 2.3 import "actions" import "stores" ApplicationWindow { id: appWindow visible: true width: 640 height: 480 Button { anchors.fill: parent font.pointSize: 20 text: "Login" onClicked: { AppActions.login(); } } Component.onCompleted: { UserStore; // If this line is removed, AppActions.login is not received by UserStore } }The link below is the project in its entirety, which also includes two trace files from the profiler:
trace_good.qztandtrace_bad.qzt. In the latter trace it clearly shows that theUserStoreis not properly created.Project: test.zip
Build kit used: Qt 5.13.0 MSVC2017 64bit -
Singletons are created by demand only and
qmldircan't help you here. Your workaround probably is the best way for your case. Maybe you should change architecture of your app, some sort of dispatcher can be useful here. Here is a good example: QML Flux. -
Singletons are created by demand only and
qmldircan't help you here. Your workaround probably is the best way for your case. Maybe you should change architecture of your app, some sort of dispatcher can be useful here. Here is a good example: QML Flux.@IntruderExcluder https://github.com/benlau/quickflux/issues/26
I had originally started down the path of this issue using QuickFlux, but the issue lay with the singleton pattern. This is how BenLau creates his actions and stores in his example projects.
I had used QuickFlux once before and I don't recall having this same problem then, only now has it come to my attention.