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. Use a c++ class as singleton inside qml files
Forum Updated to NodeBB v4.3 + New Features

Use a c++ class as singleton inside qml files

Scheduled Pinned Locked Moved QML and Qt Quick
15 Posts 4 Posters 9.9k 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.
  • B Offline
    B Offline
    billouparis
    wrote on 10 Jun 2011, 08:30 last edited by
    #1

    Hello I have the following question:

    I have a C++ class called MyClass
    I declared the class with the following macro at the end of the MyClass.h header file:

    @
    QML_DECLARE_TYPE(MyClass)
    @

    In the main application main.c file I have the following line:

    @
    qmlRegisterType<MyClass>("MyLibrary", 1, 0, "MyClass");
    @

    then I have three different QML files
    1 - first file is MyClassAdaptor.qml and it declares the instance of the MyClass like this:

    @
    Rectangle {

        MyClass {
                     id: myClassID
                     ...
        }
    

    }
    @

    2&3 - the second and third files both declare the MyClassAdaptor object like this:
    file2:

    @
    Rectangle {
    MyClassAdaptor {
    ...
    }
    }
    @

    file3

    @
    Rectangle {
    MyClassAdaptor {
    ...
    }
    }
    @

    When starting this application, I noted that my MyClass constructor is called twice, leading to two different instances of the same C++ MyClass object.
    What I am trying to do is to have only one instance of the MyClass object.

    I know one way is to implement a singleton class pattern directly in C++, but I was wondering if there were another option to achieve this, that would only have impact in the QML files. I would not like to be obliged to modify the C++ file at all. If somebody has got any solution to perform this only by modifying the QML files, your help would be greatly appreciated.

    Further, I would also like to implement a mechanism in QML only to be able to know how many and which QML objects are currently declaring the instance of MyClass so as to be able to manage the number of signals potentially being sent to the different QML object implementing the MyClassAdaptor file.

    Thank you for your answer,
    Bill

    [EDIT: code formatting, please wrap in @-tags, Volker]

    1 Reply Last reply
    0
    • T Offline
      T Offline
      thisisbhaskar
      wrote on 10 Jun 2011, 08:49 last edited by
      #2

      Very interesting question.. I am not sure how to do it in qml only.. but I had faced similar problem before and this is how I solved it..

      I created an instance of MyClass in my c++ and exported it as a property to qml with

      @QmlApplicationViewer viewer;
      MyClass tempClass; // my c++ class
      QDeclarativeContext * context = viewer.rootContext();
      context->setContextProperty("objectQml",&tempClass);@

      In all the places you want to have single object, you can use objectQml to set properties and make method calls.

      I am looking to know how to do it only in qml :)

      1 Reply Last reply
      0
      • B Offline
        B Offline
        billouparis
        wrote on 10 Jun 2011, 09:22 last edited by
        #3

        Hello Vijay,
        thank you for your answer. I also thought of this in the beginning but then I was stuck with the signals coming from MyClass, i had no idea how to get them on the QML side, using the "onSignal" mechanism.
        Do you know if it's possible to implement in QML something like "objectQML.onSignal" inside my MyClassAdaptor.qml file?
        With the current solution it is easy to have this in MyClassAdaptor

        @
        Rectangle {
        MyClass {
        onSignal : --perform some action
        }
        @

        Now how can I achieve this with your solution? Can I declare the objectQML somewhere in my MyClassAdaptor file, and how?

        Thank you,
        Bill

        [EDIT: code formatting, please wrap in @-tags, Volker]

        1 Reply Last reply
        0
        • G Offline
          G Offline
          geronik
          wrote on 10 Jun 2011, 11:15 last edited by
          #4

          What about the link below

          "http://developer.qt.nokia.com/forums/viewthread/6201":http://developer.qt.nokia.com/forums/viewthread/6201

          1 Reply Last reply
          0
          • T Offline
            T Offline
            thisisbhaskar
            wrote on 10 Jun 2011, 11:16 last edited by
            #5

            Wow.. interesting. I don't know how to do it. Let me find sometime to find out.

            1 Reply Last reply
            0
            • T Offline
              T Offline
              thisisbhaskar
              wrote on 14 Jun 2011, 06:33 last edited by
              #6

              ok.. one thing you can do is to connect your MyClass's onSignal some signal in your qml code.

              @QObject * root = viewer->rootObject();
              QObject *qmlItem = obj->findChild<QObject *>("qmlItem "); // "qmlItem" is objectName of one of your qml items.
              QObject::connect(&MyClass, SIGNAL(onSignal ()),qmlItem, SIGNAL(qmlItemSignal ()));@

              try it out and let us know if this works.

              1 Reply Last reply
              0
              • B Offline
                B Offline
                billouparis
                wrote on 14 Jun 2011, 08:05 last edited by
                #7

                Hello Vijay,

                Yes I kinda tested the "connect" thing and it worked, but it is not satisfying for me, as I may have multiple classes from which I will have to handle signals and link them to several different qml files, and I don't want to have all of them managed in my main.c file, at all. I would like everything to be handled in the QML part really.

                By the way, do you have a solution to create a singleton from within QML only?

                thank you,
                Bill

                1 Reply Last reply
                0
                • T Offline
                  T Offline
                  thisisbhaskar
                  wrote on 14 Jun 2011, 08:46 last edited by
                  #8

                  ok :). One more thought. Have your MyClass qml instance in your root class ( I mean main.qml rootitem), and have a javascript function which finds root item, and then gets your class id.

                  your javascript class something like this

                  @function getSingleton(var currentItem)
                  {
                  var parentItem = currentItem
                  while(parentItem) {
                  parentItem = parentItem.parent
                  }
                  return parentItem.mySingletonItem
                  }@

                  Don't know if this works, but worth giving a try.

                  1 Reply Last reply
                  0
                  • B Offline
                    B Offline
                    billouparis
                    wrote on 14 Jun 2011, 09:13 last edited by
                    #9

                    Hello Vijay, thank you for your new suggestion.
                    Where do I put this javascript function, and how do I declare an instance of MyClass that would be the return value of this function? I didn't understand, sorry.
                    Bill

                    1 Reply Last reply
                    0
                    • T Offline
                      T Offline
                      thisisbhaskar
                      wrote on 14 Jun 2011, 09:29 last edited by
                      #10

                      I will try this out and let you know if this work. I should post the complete code example in case if it works.

                      1 Reply Last reply
                      0
                      • B Offline
                        B Offline
                        billouparis
                        wrote on 14 Jun 2011, 09:40 last edited by
                        #11

                        I'm trying to do it on my side in the mean time too, and try to make it make some sense to me ;)
                        Thank you Vijay, I stay tuned!
                        Bill

                        1 Reply Last reply
                        0
                        • B Offline
                          B Offline
                          billouparis
                          wrote on 15 Jun 2011, 08:50 last edited by
                          #12

                          Got an answer from guyz @ Nokia telling me it was not a good idea in the first place, and that the singleton implementation should remain withinj the C++ code. So I think that settles it!

                          1 Reply Last reply
                          0
                          • T Offline
                            T Offline
                            thisisbhaskar
                            wrote on 15 Jun 2011, 09:01 last edited by
                            #13

                            oho ok.. but whey is it not a good idea to have a singleton class in QML. Does it mean that we are not advised to have business logic in QML and move it to c++. And mostly we don't want to have singleton class for a displayable item and keeps moving it around??

                            1 Reply Last reply
                            0
                            • B Offline
                              B Offline
                              billouparis
                              wrote on 15 Jun 2011, 09:20 last edited by
                              #14

                              Here is their whole answer

                              "I have been thinking about this for a while, but didn't come up with a good solution. Besides, it feels wrong somehow trying to apply this OOP pattern to a declarative language like QML. There might be some tweaks in Javascript, but I would rather suggest to solve this in C++ or take a different approach. I mean even, if you would implement your declarative item as a singleton, the QML engine couldn't instantiate it, as it needs a public constructor."

                              Regards,
                              Bill

                              1 Reply Last reply
                              0
                              • G Offline
                                G Offline
                                Gagi
                                wrote on 4 Nov 2011, 19:58 last edited by
                                #15

                                I know it's a old question but, did you tried to connect to the exported property using a Connections item ?

                                @
                                Connections {
                                target: objectQml
                                onSignal: //dosomething
                                }
                                @

                                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