[SOLVED] QML Singleton Problem



  • I specified
    @
    pragma singleton
    @

    as the first line in MySingleton.qml and have
    @property string myText: “”
    @

    in MySingleton.qml, specified
    @
    import “.”
    @

    at the top of main.qml, and added the qmldir file in their common directory with
    @
    singleton MySingleton MySingleton.qml
    @

    When I have
    @
    property string mySingletonText: MySingleton.myText
    @

    in main.qml I get the error

    bq. qrc:/qml/main.qml:11: ReferenceError: MySingleton is not defined

    but MySingleton.qml is specified in my .pro and .qrc files.

    When I have
    @
    MySingleton{
    id: singleton
    }
    @

    in main.qml I get the error

    bq. qrc:/qml/MySingleton.qml:1:1: pragma Singleton used with a non composite singleton type MySingleton

    I tried this because I assumed (perhaps mistakenly) that this would be the way to access signals and functions.

    Any help would be appreciated.

    Thanks.

    Steve



  • [quote author="SteveG" date="1394399218"]I specified
    @
    pragma singleton
    @

    as the first line in MySingleton.qml and have
    @property string myText: “”
    @

    in MySingleton.qml, specified
    @
    import “.”
    @

    at the top of main.qml, and added the qmldir file in their common directory with
    @
    singleton MySingleton MySingleton.qml
    @

    When I have
    @
    property string mySingletonText: MySingleton.myText
    @

    in main.qml I get the error

    bq. qrc:/qml/main.qml:11: ReferenceError: MySingleton is not defined

    but MySingleton.qml is specified in my .pro and .qrc files.
    [/quote]

    There is a limitation with QML-only singletons at the moment - you need to use a full module import with a qmldir file and not just a directory import (with implicit qmldir file). So import "." will not work, you'll need a qmldir file like

    @
    singleton MySingleton 1.0 MySingleton.qml
    @

    and then import it via a module import (something like 'import MyModule 1.0', not 'import "relative/dir"').



  • Alan,

    I'll try what you suggested. Is this "limitation" due to a bug because I followed a documented approach that didn't work?

    BTW, are there any plans to allow QML singletons to have signals and functions that other QML types can respond to and call, respectively?

    Thank you.

    Steve



  • Alan,

    I have the qmldir file in my qml directory and changed the contents to
    @
    singleton MyNewSingleton 1.0 MySingleton.qml
    @

    I also changed the import statement to
    @
    import MyNewSingleton 1.0
    @

    but Qt Creator 3.0.1 shows this with a red underline and I get the error message

    bq. qrc:/qml/main.qml:2:1: module "MyNewSingleton" is not installed

    when I run my project. I even added
    @
    QML_IMPORT_PATH += $$PWD/qml
    @

    to my .pro file but it made no difference.

    Do I need to add qmlRegisterSingletonType or something similar to my main.cpp file?

    Thanks.

    Steve



  • [quote author="SteveG" date="1394799985"]
    I'll try what you suggested. Is this "limitation" due to a bug because I followed a documented approach that didn't work?
    [/quote]
    It's a limitation of the current implementation that we hope to remove some day. The docs are not... that great right now.

    [quote author="SteveG" date="1394799985"]
    BTW, are there any plans to allow QML singletons to have signals and functions that other QML types can respond to and call, respectively?
    [/quote]

    They already have that, like any exposed QObject.

    [quote author="SteveG" date="1394801664"]Alan,

    I have the qmldir file in my qml directory and changed the contents to
    @
    singleton MyNewSingleton 1.0 MySingleton.qml
    @

    I also changed the import statement to
    @
    import MyNewSingleton 1.0
    @

    but Qt Creator 3.0.1 shows this with a red underline and I get the error message

    bq. qrc:/qml/main.qml:2:1: module "MyNewSingleton" is not installed

    when I run my project. I even added
    @
    QML_IMPORT_PATH += $$PWD/qml
    @

    to my .pro file but it made no difference.
    [/quote]

    That's not how imports work (they operate on folders, not types). If you added the qml directory as an import path, then the module import you used would be looking for a folder $$PWD/qml/MyNewSingleton .

    But you can also import a relative directory, like
    @
    import "MySingletonsDir"
    @

    or

    @
    import "."
    @

    So long as it's a directory with that qmldir file, it should pick up the
    singleton type.



  • Alan,

    I've tried several gyrations and still can't get it to work. Please let me know the following.

    1. What should the directory structure be?
      @
      I have:

    main.cpp
    simpleSingleton.pro
    simpleSingleton.qrc
    qml - Directory
    main.qml
    MyNewSingleton - Directory
    MySingleton.qml
    qmldir
    @

    1. What should the qmldir file contain and where should it reside?
      @
      I have:

    singleton MyNewSingleton MySingleton.qml
    @

    1. Where should the QML singleton file reside?
    2. What should the .pro file contain?
      @
      I have:

    QT += qml quick

    TARGET = SimpleSingletonTest

    RESOURCES += simpleSingletonTest.qrc

    SOURCES += $$PWD/main.cpp

    OTHER_FILES +=
    qml/main.qml
    qml/MyNewSingleton/MySingleton.qml
    @

    1. What should the .qrc file contain?
      @
      I have:

    <RCC>
    <qresource prefix="/">
    <file>qml/main.qml</file>
    <file>qml/MyNewSingleton/MySingleton.qml</file>
    </qresource>
    </RCC>
    @

    1. What should the import in main.qml be?
      @
      I have:

    import "MyNewSingleton"
    @

    1. How should the QML singleton be referenced in main.qml?
      @
      I have:

    property string mySingleton1: MyNewSingleton.intProperty
    property string mySingleton2: MySingleton.intProperty

    which results in
    qrc:/qml/main.qml:10: ReferenceError: MyNewSingleton is not defined
    qrc:/qml/main.qml:11: ReferenceError: MySingleton is not defined
    @

    bq. They already have that, like any exposed QObject.

    Can you reference an example where a QML singleton has signals and funcions that are used by another QML type?

    Thanks.

    Steve



  • I think you just missed the version number on the import (actually important in this case, I should have mentioned this).

    Here's a quick example that I whipped up and verified to work. It just runs using the qml binary, but the adaptation to use a custom C++ shell and QRC should be straightforward:

    ./main.qml:
    @
    import QtQuick.Window 2.1
    import QtQuick 2.1
    import "MyDir" 1.0

    Window {
    width: 480
    height: 360
    color: "lightsteelblue"
    visible: true
    Rectangle {
    id: col
    anchors.fill: parent
    anchors.margins: 48
    color: "goldenrod"
    Text {
    id: txt
    text: CentralData.textual
    anchors.centerIn: parent
    }
    Connections {
    target: CentralData
    onTock: txt.text = "tock"
    }
    MouseArea {
    anchors.fill: parent
    onClicked: CentralData.tick(txt);
    }
    }
    }
    @

    ./MyDir/qmldir:
    @
    singleton CentralData 1.0 CentralData.qml
    @

    ./MyDir/CentralData.qml:
    @
    pragma Singleton
    import QtQml 2.0

    QtObject {
    id: single
    property string textual: "Initial String"
    signal tock
    function tick(obj) {
    obj.text = "tick"
    }
    property QtObject tim: Timer {
    interval: 1500
    repeat: true
    running: true
    onTriggered: single.tock();
    }
    }
    @

    Of course, it's shameful that there isn't a proper example somewhere. I should add one...



  • Alan,

    bq. the adaptation to use a custom C++ shell and QRC should be straightforward

    It's not. Your example runs with qmlscene but I can't get it to work with a main.cpp and .pro and .qrc files, even with modifying one or both of your QML files. Can you whip up something based on your example?

    Thanks.

    Steve



  • Alan,

    One more thing. When I mouse over the import "MyDir" 1.0 statement in Qt Creator 3.0.1 it correctly shows the location of MyDir. However, when I run the project I get the error message

    bq. qrc:/qml/main.qml:3:1: "MyDir": no such directory

    When I specify import "." instead, I get several error messages like

    bq. qrc:/qml/main.qml:21: ReferenceError: CentralData is not defined

    Steve



  • [quote author="SteveG" date="1395198709"]Alan,

    bq. the adaptation to use a custom C++ shell and QRC should be straightforward

    It's not. Your example runs with qmlscene but I can't get it to work with a main.cpp and .pro and .qrc files, even with modifying one or both of your QML files. Can you whip up something based on your example?
    [/quote]

    Sure. To save time, I didn't spend any thinking on good names for the files ;) . Tested with Qt 5.2.1.

    Only thing that wasn't straightforward when I tried is that QQmlApplcationEngine's string constructor didn't seem to recognize the 'qrc:' (probably documented behavior). Wrapping with the QUrl constructor solved that.

    main.cpp:
    @
    #include <QtGui/QGuiApplication>
    #include <QtQml/QQmlApplicationEngine>

    int main(int argc, char *argv[])
    {
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine qqae(QUrl("qrc:///qml/testable2/main.qml"));
    return app.exec();
    }
    @

    testable.pro:
    @
    TEMPLATE = app
    SOURCES += main.cpp
    QT += qml

    RESOURCES +=
    res.qrc
    @

    res.qrc:
    @
    <RCC>
    <qresource prefix="/" lang="qml">
    <file>qml/testable2/main.qml</file>
    <file>qml/testable2/MyDir/CentralData.qml</file>
    <file>qml/testable2/MyDir/qmldir</file>
    </qresource>
    </RCC>
    @



  • Alan,

    I added the qmldir file to my .qrc file and it now works.

    THANK YOU!!!

    Steve

    BTW, you may want to include this example in Qt 5.3 or later.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.