Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Registering C++ objects in QML
Forum Updated to NodeBB v4.3 + New Features

Registering C++ objects in QML

Scheduled Pinned Locked Moved Solved General and Desktop
22 Posts 7 Posters 2.7k 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.
  • J JonB
    17 Sept 2019, 16:32

    [Forked from: https://forum.qt.io/topic/106926/emiting-signals-from-singletons ~kshegunov]

    Just to be clear,

    Database* Database::getInstance()
    {
      static Database* inst = new Database();
      return inst;
    }
    

    inst will only be initialized, and new Database() called, once. That's been true since C. So indeed no leak.

    It will be initialized only the first time a thread of execution reaches its definition.

    That is interesting! I wonder how they define that, and how they achieve it in generated code.

    J Offline
    J Offline
    J.Hilk
    Moderators
    wrote on 18 Sept 2019, 04:55 last edited by
    #2

    @jonb very true, no idea what possessed me to write that, crossed the statement from my post.

    @stehlo
    glad to be of help, when I can 😉
    Happy coding!


    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


    Q: What's that?
    A: It's blue light.
    Q: What does it do?
    A: It turns blue.

    1 Reply Last reply
    1
    • C Offline
      C Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on 18 Sept 2019, 05:02 last edited by
      #3

      @jonb said in Emiting signals from singletons:

      I wonder how they define that, and how they achieve it in generated code.

      https://godbolt.org/z/okdC7k

      The second implementation should be preferred in C++11 afaik

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      C J 2 Replies Last reply 18 Sept 2019, 05:40
      2
      • C Christian Ehrlicher
        18 Sept 2019, 05:02

        @jonb said in Emiting signals from singletons:

        I wonder how they define that, and how they achieve it in generated code.

        https://godbolt.org/z/okdC7k

        The second implementation should be preferred in C++11 afaik

        C Offline
        C Offline
        Chris Kawa
        Lifetime Qt Champion
        wrote on 18 Sept 2019, 05:40 last edited by Chris Kawa
        #4

        @christian-ehrlicher said in Emiting signals from singletons:

        The second implementation should be preferred in C++11 afaik

        In general yes, but not for QObjects, as the static instance could outlive the application object. That is an error and can lead to crashes on shutdown, which often go unnoticed because the app is exiting anyway and thus causes subtle bugs because some destructors might not be called.

        For QObjects something like this can be used:

        Foo* getInstance()
        {
            static Foo* s_inst = nullptr;
            if (!s_inst)
            {
                s_inst = new Foo();
                QObject::connect(qApp, &QCoreApplication::aboutToQuit, s_inst,  &Foo::deleteLater);
            }
            return s_inst;
        }
        

        or, if you don't want to pay for that if on every call, you can explicitly delete that singleton somewhere before the app quits, but that tends to lead to errors if you forget.

        D 1 Reply Last reply 19 Sept 2019, 11:45
        4
        • C Offline
          C Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on 18 Sept 2019, 05:55 last edited by
          #5

          @chris-kawa said in Emiting signals from singletons:

          but not for QObjects

          You're right - so connecting to aboutToQuit or use qAddPostRoutine() should be used here.

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          C 1 Reply Last reply 18 Sept 2019, 06:09
          2
          • C Christian Ehrlicher
            18 Sept 2019, 05:55

            @chris-kawa said in Emiting signals from singletons:

            but not for QObjects

            You're right - so connecting to aboutToQuit or use qAddPostRoutine() should be used here.

            C Offline
            C Offline
            Chris Kawa
            Lifetime Qt Champion
            wrote on 18 Sept 2019, 06:09 last edited by
            #6

            @christian-ehrlicher said in Emiting signals from singletons:

            You're right - so connecting to aboutToQuit or use qAddPostRoutine() should be used here.

            Yeah, you just have to be careful with qAddPostRoutine() if your singleton lives in a dynamically loaded library, as the cleanup code could try to call something from an unloaded lib.

            Another problem with this is that this getInstance() can be called before qApp is created or after it is destroyed (often happens in destructors). I would add an extra check to see if qApp is null and return nullptr, add an assertion, throw an exception or do whatever your favorite way of handling errors is.

            1 Reply Last reply
            3
            • C Christian Ehrlicher
              18 Sept 2019, 05:02

              @jonb said in Emiting signals from singletons:

              I wonder how they define that, and how they achieve it in generated code.

              https://godbolt.org/z/okdC7k

              The second implementation should be preferred in C++11 afaik

              J Offline
              J Offline
              JonB
              wrote on 18 Sept 2019, 10:34 last edited by
              #7

              @christian-ehrlicher
              I looked at the generated code you linked to. very interesting: as i suspected, it implements "first time executed only" via a "guard variable" :)

              1 Reply Last reply
              0
              • C Chris Kawa
                18 Sept 2019, 05:40

                @christian-ehrlicher said in Emiting signals from singletons:

                The second implementation should be preferred in C++11 afaik

                In general yes, but not for QObjects, as the static instance could outlive the application object. That is an error and can lead to crashes on shutdown, which often go unnoticed because the app is exiting anyway and thus causes subtle bugs because some destructors might not be called.

                For QObjects something like this can be used:

                Foo* getInstance()
                {
                    static Foo* s_inst = nullptr;
                    if (!s_inst)
                    {
                        s_inst = new Foo();
                        QObject::connect(qApp, &QCoreApplication::aboutToQuit, s_inst,  &Foo::deleteLater);
                    }
                    return s_inst;
                }
                

                or, if you don't want to pay for that if on every call, you can explicitly delete that singleton somewhere before the app quits, but that tends to lead to errors if you forget.

                D Offline
                D Offline
                deleted379
                wrote on 19 Sept 2019, 11:45 last edited by deleted379
                #8
                This post is deleted!
                1 Reply Last reply
                0
                • C Offline
                  C Offline
                  Chris Kawa
                  Lifetime Qt Champion
                  wrote on 19 Sept 2019, 14:19 last edited by
                  #9

                  @stehlo The aboutToQuit signal is meant for exactly such last minute cleanup and should definitely not be avoided. It's possible that there's bug in Qt itself, however I suspect the error is more likely to be in your code. In either case I'd debug the thing first before jumping to conclusions and no matter where the bug is - fix it or report a bug in Qt.

                  Can you provide a minimal example that exhibits this problem or a stack trace of the crash from your app?

                  D 1 Reply Last reply 19 Sept 2019, 16:26
                  2
                  • C Chris Kawa
                    19 Sept 2019, 14:19

                    @stehlo The aboutToQuit signal is meant for exactly such last minute cleanup and should definitely not be avoided. It's possible that there's bug in Qt itself, however I suspect the error is more likely to be in your code. In either case I'd debug the thing first before jumping to conclusions and no matter where the bug is - fix it or report a bug in Qt.

                    Can you provide a minimal example that exhibits this problem or a stack trace of the crash from your app?

                    D Offline
                    D Offline
                    deleted379
                    wrote on 19 Sept 2019, 16:26 last edited by deleted379
                    #10
                    This post is deleted!
                    C 1 Reply Last reply 19 Sept 2019, 17:49
                    0
                    • K Offline
                      K Offline
                      kshegunov
                      Moderators
                      wrote on 19 Sept 2019, 16:32 last edited by kshegunov
                      #11

                      Actually the "best" singleton is one that you don't create. When I need the global scope I usually do what QCoreApplication does:

                      class MyGlobalClass : public QObject
                      {
                          static MyGlobalClass * p;
                      
                      public:
                          inline MyGlobalClass(QObject * parent)
                              : QObject(parent)
                          {
                              Q_ASSERT(!p);
                              p = this;
                          }
                      
                          ~MyGlobalClass() override
                          {
                              p = nullptr;
                          ]
                      
                           inline static MyGlobalClass * instance()
                           {
                                // Q_ASSERT(p); can be added optionally.
                                return p;
                           }
                      };
                      
                      MyGlobalClass * MyGlobalClass::p = nullptr;
                      

                      and I create it where it's supposed to go - in the stack (somewhere):

                      int main(int argc, char ** argv)
                      {
                           QCoreApplication app;
                           MyGlobalClass theObject(&app);
                           // ...
                           return ...
                      }
                      

                      I continue to claim that a "singleton" is nothing more than a glorified global variable, so it should be treated exactly as such - a bad monstrously stupid idea in 99.999% of cases!

                      Read and abide by the Qt Code of Conduct

                      D 1 Reply Last reply 19 Sept 2019, 16:51
                      3
                      • K kshegunov
                        19 Sept 2019, 16:32

                        Actually the "best" singleton is one that you don't create. When I need the global scope I usually do what QCoreApplication does:

                        class MyGlobalClass : public QObject
                        {
                            static MyGlobalClass * p;
                        
                        public:
                            inline MyGlobalClass(QObject * parent)
                                : QObject(parent)
                            {
                                Q_ASSERT(!p);
                                p = this;
                            }
                        
                            ~MyGlobalClass() override
                            {
                                p = nullptr;
                            ]
                        
                             inline static MyGlobalClass * instance()
                             {
                                  // Q_ASSERT(p); can be added optionally.
                                  return p;
                             }
                        };
                        
                        MyGlobalClass * MyGlobalClass::p = nullptr;
                        

                        and I create it where it's supposed to go - in the stack (somewhere):

                        int main(int argc, char ** argv)
                        {
                             QCoreApplication app;
                             MyGlobalClass theObject(&app);
                             // ...
                             return ...
                        }
                        

                        I continue to claim that a "singleton" is nothing more than a glorified global variable, so it should be treated exactly as such - a bad monstrously stupid idea in 99.999% of cases!

                        D Offline
                        D Offline
                        deleted379
                        wrote on 19 Sept 2019, 16:51 last edited by
                        #12
                        This post is deleted!
                        K 1 Reply Last reply 19 Sept 2019, 19:03
                        0
                        • D deleted379
                          19 Sept 2019, 16:26

                          This post is deleted!

                          C Offline
                          C Offline
                          Christian Ehrlicher
                          Lifetime Qt Champion
                          wrote on 19 Sept 2019, 17:49 last edited by
                          #13

                          @stehlo said in Emiting signals from singletons:

                          This is an inappropriate statement because I have specifically mentioned that I arrived at the fix after an extensive testing session. I have most definitely not jumped to any conclusions out of the blue.

                          It is a correct statement since, as @Chris-Kawa already mentioned a correct way to clean up stuff before the application ends and it works correctly. So the problem must be on your side but since you don't provide code we can't help.

                          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                          Visit the Qt Academy at https://academy.qt.io/catalog

                          1 Reply Last reply
                          0
                          • C Offline
                            C Offline
                            Christian Ehrlicher
                            Lifetime Qt Champion
                            wrote on 19 Sept 2019, 18:09 last edited by
                            #14

                            Deleting the topic for sure helps to fix the problems...

                            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                            Visit the Qt Academy at https://academy.qt.io/catalog

                            D 1 Reply Last reply 19 Sept 2019, 18:34
                            1
                            • C Christian Ehrlicher
                              19 Sept 2019, 18:09

                              Deleting the topic for sure helps to fix the problems...

                              D Offline
                              D Offline
                              deleted379
                              wrote on 19 Sept 2019, 18:34 last edited by
                              #15
                              This post is deleted!
                              A 1 Reply Last reply 19 Sept 2019, 19:09
                              0
                              • D deleted379
                                19 Sept 2019, 16:51

                                This post is deleted!

                                K Offline
                                K Offline
                                kshegunov
                                Moderators
                                wrote on 19 Sept 2019, 19:03 last edited by
                                #16

                                @stehlo said in Emiting signals from singletons:

                                How do you use such a construct as an object in QML?

                                As a context property?

                                Read and abide by the Qt Code of Conduct

                                1 Reply Last reply
                                0
                                • D deleted379
                                  19 Sept 2019, 18:34

                                  This post is deleted!

                                  A Offline
                                  A Offline
                                  aha_1980
                                  Lifetime Qt Champion
                                  wrote on 19 Sept 2019, 19:09 last edited by
                                  #17

                                  @stehlo It is your right to use the support that fits you best.

                                  But once you asked in public, and many people tried to help you, these answers should stay public.

                                  So I've restored the post, and I ask to to keep it that way. Thanks!

                                  Qt has to stay free or it will die.

                                  D 1 Reply Last reply 19 Sept 2019, 19:16
                                  1
                                  • A aha_1980
                                    19 Sept 2019, 19:09

                                    @stehlo It is your right to use the support that fits you best.

                                    But once you asked in public, and many people tried to help you, these answers should stay public.

                                    So I've restored the post, and I ask to to keep it that way. Thanks!

                                    D Offline
                                    D Offline
                                    deleted379
                                    wrote on 19 Sept 2019, 19:16 last edited by
                                    #18
                                    This post is deleted!
                                    K 1 Reply Last reply 19 Sept 2019, 19:30
                                    0
                                    • D deleted379
                                      19 Sept 2019, 19:16

                                      This post is deleted!

                                      K Offline
                                      K Offline
                                      kshegunov
                                      Moderators
                                      wrote on 19 Sept 2019, 19:30 last edited by
                                      #19

                                      @stehlo said in Registering C++ objects in QML:

                                      Therefore, I insist on the removal of this tainted topic without any further discussions.

                                      It'd been forked in its own topic. Which should satisfy your request, shouldn't it?

                                      Read and abide by the Qt Code of Conduct

                                      1 Reply Last reply
                                      2
                                      • J Offline
                                        J Offline
                                        J.Hilk
                                        Moderators
                                        wrote on 20 Sept 2019, 05:47 last edited by
                                        #20

                                        Wow this escalated quickly!

                                        I think the fork is a good idea, tbh.

                                        @kshegunov said in Registering C++ objects in QML:

                                        I continue to claim that a "singleton" is nothing more than a glorified global variable, so it should be treated exactly as such - a bad monstrously stupid idea in 99.999% of cases!

                                        sadly, in combination with QML your options are limited. If you want to access the class from cpp and QML you can do one of the following

                                        • Singleton, instance in cpp and exactly where you need it in qml
                                        • Normal instance in cpp, a global property accessible in all qml files
                                        • using find child to search for your qml item and do the connect in cpp. This falls apart as soon as you start to dynamically load your qml files

                                        So, Pest Cholera, or Malaria.

                                        @stehlo said in Registering C++ objects in QML:

                                        Without going into extra detail which would detract from the main point, the attempt to deleteLater the QObject unnaturally at the point of the application being aboutToQuit causes either of the two following fatal errors, depending on whether we do this for the networking singleton or the database one:

                                        QObject: shared QObject was deleted directly. The program is malformed and may crash.
                                        abort_message: assertion "Pure virtual function called!" failed
                                        Fatal signal 6 (SIGABRT), Aborted

                                        or

                                        null pointer dereference
                                        Fatal signal 11 (SIGSEGV), Segmentation fault

                                        The attempt to deleteLater is happening either too early or two late.

                                        I actually have to disagree.
                                        after reading the post by @Chris-Kawa I changed my own project to include the about to quit cleanup. That's for about 10 Singletons not once did I have one of your errors mentions above.

                                        I would say there's still something going on that causes your issue, but I think it's user -rather than framework related


                                        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                        Q: What's that?
                                        A: It's blue light.
                                        Q: What does it do?
                                        A: It turns blue.

                                        K 1 Reply Last reply 20 Sept 2019, 08:11
                                        2
                                        • J J.Hilk
                                          20 Sept 2019, 05:47

                                          Wow this escalated quickly!

                                          I think the fork is a good idea, tbh.

                                          @kshegunov said in Registering C++ objects in QML:

                                          I continue to claim that a "singleton" is nothing more than a glorified global variable, so it should be treated exactly as such - a bad monstrously stupid idea in 99.999% of cases!

                                          sadly, in combination with QML your options are limited. If you want to access the class from cpp and QML you can do one of the following

                                          • Singleton, instance in cpp and exactly where you need it in qml
                                          • Normal instance in cpp, a global property accessible in all qml files
                                          • using find child to search for your qml item and do the connect in cpp. This falls apart as soon as you start to dynamically load your qml files

                                          So, Pest Cholera, or Malaria.

                                          @stehlo said in Registering C++ objects in QML:

                                          Without going into extra detail which would detract from the main point, the attempt to deleteLater the QObject unnaturally at the point of the application being aboutToQuit causes either of the two following fatal errors, depending on whether we do this for the networking singleton or the database one:

                                          QObject: shared QObject was deleted directly. The program is malformed and may crash.
                                          abort_message: assertion "Pure virtual function called!" failed
                                          Fatal signal 6 (SIGABRT), Aborted

                                          or

                                          null pointer dereference
                                          Fatal signal 11 (SIGSEGV), Segmentation fault

                                          The attempt to deleteLater is happening either too early or two late.

                                          I actually have to disagree.
                                          after reading the post by @Chris-Kawa I changed my own project to include the about to quit cleanup. That's for about 10 Singletons not once did I have one of your errors mentions above.

                                          I would say there's still something going on that causes your issue, but I think it's user -rather than framework related

                                          K Offline
                                          K Offline
                                          kshegunov
                                          Moderators
                                          wrote on 20 Sept 2019, 08:11 last edited by kshegunov
                                          #21

                                          @j-hilk said in Registering C++ objects in QML:

                                          Normal instance in cpp, a global property accessible in all qml files

                                          What I wrote. Normal object in C++, a context property in QML. Which is kind of the point of having context properties to begin with, is it not?

                                          Read and abide by the Qt Code of Conduct

                                          J 1 Reply Last reply 20 Sept 2019, 08:17
                                          0

                                          11/22

                                          19 Sept 2019, 16:32

                                          • Login

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