Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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
        qmldir
    

    Both AppActions and UserStore are marked with pragma Singleton and are marked as singletons in their corresponding qmldir files. In AppActions a signal is declared, and in UserStore a connection is made to that signal. This signal is emitted upon the receipt of onClicked in a Button in main.qml.

    At first glance, the signal is not received by UserStore because UserStore does not exist. Only upon adding a no-op call of UserStore; in main.qml is the UserStore created and the signal properly received. From what I understand, the singleton types ought to be instantiated given the presence of the qmldir files.

    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.qzt and trace_bad.qzt. In the latter trace it clearly shows that the UserStore is not properly created.

    Project: test.zip
    Build kit used: Qt 5.13.0 MSVC2017 64bit



  • Singletons are created by demand only and qmldir can'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.


Log in to reply