Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. HOWTO access members of a Singleton QML Object type from C++

HOWTO access members of a Singleton QML Object type from C++

Scheduled Pinned Locked Moved Solved QML and Qt Quick
7 Posts 2 Posters 3.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • V Offline
    V Offline
    vikramg
    wrote on 9 Nov 2018, 00:25 last edited by
    #1

    I'm trying to access properties of an "App Settings" QML object from C++. Per various examples, I have made it a singleton, since its only purpose is to provide some settings properties.

    I tried to follow the examples here:
    http://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html
    to access these properties from C++ via:

    QQmlComponent component(&engine, QUrl(QStringLiteral("qrc:/AppConfig/Config.qml")));
    QObject *object = component.create();
    int myWidth = QQmlProperty::read(object, "width").toInt();
    

    But this works only when the object is not marked pragma Singleton -- presumably because we are actually instantiating the object in the component.create(), which the singleton disallows.

    Is there any way around this? [Incidentally, the other QQuickView method doesn't work at all, even on non-singleton objects, because the object is a QtObject and not an Item.]

    1 Reply Last reply
    0
    • D Offline
      D Offline
      dheerendra
      Qt Champions 2022
      wrote on 10 Nov 2018, 08:02 last edited by dheerendra 11 Oct 2018, 08:02
      #2

      It should work as is. It should not make any difference.. Can you post your config.qml ?

      Dheerendra
      @Community Service
      Certified Qt Specialist
      http://www.pthinks.com

      1 Reply Last reply
      0
      • V Offline
        V Offline
        vikramg
        wrote on 10 Nov 2018, 18:52 last edited by
        #3

        AppConfig/Config.qml:

        import QtQuick 2.0
        pragma Singleton
        
        QtObject {
        
            objectName: "Config"
        
            readonly property int width: 37
            readonly property int height: 43
        }
        

        main.cpp:

        int main(int argc, char *argv[])
        {
            QGuiApplication app(argc, argv);
        
            QQmlApplicationEngine engine;
            engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
            if (engine.rootObjects().isEmpty())
                return -1;
        
            QQmlComponent component(&engine, QUrl(QStringLiteral("qrc:/AppConfig/Config.qml")));
            QObject *object = component.create();
        
            int cfgWidth = QQmlProperty::read(object, "width").toInt();
            qDebug("Config width = %d", cfgWidth);
        
            delete object;
            return app.exec();
        }
        

        This works only if I comment out the pragma Singleton from Config.qml. Otherwise it prints QQmlComponent: Component is not ready and the width read is 0.

        1 Reply Last reply
        0
        • D Offline
          D Offline
          dheerendra
          Qt Champions 2022
          wrote on 11 Nov 2018, 04:20 last edited by dheerendra 11 Nov 2018, 04:22
          #4

          I have exactly same program and tried. It works like champ. Do you have only above code in Config.qml or something also exist ? Reason is that if the component is not ready, component.create and read function should crash your program. So is it crashing ?
          Also check for isError from Component and try to get all the errors using errors() function. It should give some hints.

          Which version of Qt & platform ?

          Dheerendra
          @Community Service
          Certified Qt Specialist
          http://www.pthinks.com

          1 Reply Last reply
          0
          • V Offline
            V Offline
            vikramg
            wrote on 11 Nov 2018, 06:45 last edited by vikramg 11 Nov 2018, 06:53
            #5

            Huh!? Wow that's strange. To answer your questions:

            • Yes, that is the entirety of code in Config.qml (I deliberately created a simple example project to illustrate the problem).
            • No, the program does not crash. The default "Hello World" application window does pop up on screen. The entirety of Application Output is:
            QML debugging is enabled. Only use this in a safe environment.
            QQmlComponent: Component is not ready
            Config width = 0
            

            (When the pragma Singleton is commented out, it correctly prints Config width = 37, and the "not ready" message is not seen). I checked in the debugger, and the object is indeed a null pointer in the failing case, but surprisingly the QQmlProperty::read function does not crash; instead, it returns 0.

            • Qt version 5.9.0; platform Linux x86-64.

            I added the isError/errors() debug instrumentation as you suggested:

                QQmlComponent component(&engine, QUrl(QStringLiteral("qrc:/AppConfig/Config.qml")));
                QObject *object = component.create();
            
                if (component.isError()) {
                    for (auto e : component.errors()) {
                        qDebug() << e;
                    }
                }
            

            and in the failing case, it prints out:

            QML debugging is enabled. Only use this in a safe environment.
            QQmlComponent: Component is not ready
            <Unknown File>: No matching type found, pragma Singleton files cannot be used by QQmlComponent.
            Config width = 0
            

            This seems to bear out my original hunch that Singleton QML elements cannot be instantiated. But then how does it work for you?? Did this behavior change in later Qt versions?

            1 Reply Last reply
            0
            • D Offline
              D Offline
              dheerendra
              Qt Champions 2022
              wrote on 11 Nov 2018, 07:42 last edited by dheerendra 11 Nov 2018, 07:43
              #6

              Can you register the Config.qml component as singleton using the following statement & then try ?
              qmlRegisterSingletonType(QStringLiteral("qrc:/MyStyles.qml"),"pthinks.styles",1,0,"PthinkStyle");

              Dheerendra
              @Community Service
              Certified Qt Specialist
              http://www.pthinks.com

              1 Reply Last reply
              1
              • V Offline
                V Offline
                vikramg
                wrote on 12 Nov 2018, 00:51 last edited by
                #7

                That does indeed work! Thank you!

                qmlRegisterSingletonType(QUrl(QStringLiteral("qrc:/AppConfig/Config.qml")), "com.test.Config", 1, 0, "Config");
                
                1 Reply Last reply
                0

                1/7

                9 Nov 2018, 00:25

                • Login

                • Login or register to search.
                1 out of 7
                • First post
                  1/7
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved