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++
Forum Updated to NodeBB v4.3 + New Features

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.6k Views 1 Watching
  • 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.
  • vikramgV Offline
    vikramgV Offline
    vikramg
    wrote on 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
    • dheerendraD Offline
      dheerendraD Offline
      dheerendra
      Qt Champions 2022
      wrote on last edited by dheerendra
      #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
      • vikramgV Offline
        vikramgV Offline
        vikramg
        wrote on 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
        • dheerendraD Offline
          dheerendraD Offline
          dheerendra
          Qt Champions 2022
          wrote on last edited by dheerendra
          #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
          • vikramgV Offline
            vikramgV Offline
            vikramg
            wrote on last edited by vikramg
            #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
            • dheerendraD Offline
              dheerendraD Offline
              dheerendra
              Qt Champions 2022
              wrote on last edited by dheerendra
              #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
              • vikramgV Offline
                vikramgV Offline
                vikramg
                wrote on 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

                • Login

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