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. Creating QGuiApplication on the heap - crashes (multiple UIs via plugins)
Forum Updated to NodeBB v4.3 + New Features

Creating QGuiApplication on the heap - crashes (multiple UIs via plugins)

Scheduled Pinned Locked Moved Solved General and Desktop
13 Posts 2 Posters 4.9k Views 2 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.
  • D Offline
    D Offline
    Deckard
    wrote on last edited by Deckard
    #1

    Hi, I need to create QGuiApplication on the heap. I follow the example from
    https://doc.qt.io/qt-5/qapplication.html#details that creates QApplication in a separate function but in my function I want to return std::unique_ptr<QGuiApplication> instead of a raw QGuiApplication*.

    What I encountered are some strange looking errors depending on the way I create QGuiApplication.

    I've tried to create a minimal working program to show my problem:

    #include <memory>
    
    #include <QDebug>
    #include <QGuiApplication>
    
    
    std::unique_ptr<QGuiApplication> createApplication1(int argc, char *argv[])
    {
        // works
        std::unique_ptr<QGuiApplication> ptr(new QGuiApplication(argc,argv));
        return ptr;
    }
    
    
    std::unique_ptr<QGuiApplication> createApplication2(int argc, char *argv[])
    {
        // works
        std::unique_ptr<QGuiApplication> ptr;
        ptr.reset(new QGuiApplication(argc,argv));
        return ptr;
    }
    
    
    std::unique_ptr<QGuiApplication> createApplication3(int argc, char *argv[])
    {
        // app->exec() crashes randomly
        std::unique_ptr<QGuiApplication> ptr;
        QGuiApplication* app = new QGuiApplication(argc,argv);
        ptr.reset(app);
        return ptr;
    }
    
    
    std::unique_ptr<QGuiApplication> createApplication4(int argc, char *argv[])
    {
        // app->exec() always crashes
        return std::make_unique<QGuiApplication>(argc,argv);
    }
    
    
    int main(int argc, char *argv[])
    { 
        auto app = createApplication3(argc,argv);
    
        // auto app2 = std::make_unique<QGuiApplication>(argc,argv);
    
        // crashes with createApplication3 and createApplication4, but works with app2
        return app->exec();
    }
    

    The strange thing is the difference between createApplication2() and createApplication3() is minor (an addition of a named raw pointer) but the latter makes app->exec() crash randomly. Also, all these variants work when used directly in main() instead of a separate function, e.g. this works in main:

    auto app2 = std::make_unique<QGuiApplication>(argc,argv);
    

    but not in createApplication4().

    When the program crashes the stack trace is:

    1  __GI_raise                                                                 raise.c  58 0x7ffff5cd6fdf 
    2  __GI_abort                                                                 abort.c  89 0x7ffff5cd840a 
    3  __gnu_cxx::__verbose_terminate_handler()                                               0x7ffff65ee07d 
    4  ??                                                                                     0x7ffff65ec046 
    5  std::terminate()                                                                       0x7ffff65ec091 
    6  __cxa_throw                                                                            0x7ffff65ec2a9 
    7  qBadAlloc()                                                                            0x7ffff6dfe9b2 
    8  QListData::detach(int)                                                                 0x7ffff6e7cbba 
    9  ??                                                                                     0x7ffff6e284de 
    10 QCoreApplication::arguments()                                                          0x7ffff6fefd2f 
    11 ??                                                                                     0x7fffef97deb7 
    12 ??                                                                                     0x7fffef97ea04 
    13 _SmcProcessMessage                                                                     0x7fffef0eae45 
    14 IceProcessMessages                                                                     0x7fffeeeda33c 
    15 QMetaObject::activate(QObject *, int, int, void * *)                                   0x7ffff70185e9 
    16 QSocketNotifier::activated(int, QSocketNotifier::QPrivateSignal)                       0x7ffff70925ce 
    17 QSocketNotifier::event(QEvent *)                                                       0x7ffff7024ba2 
    18 QCoreApplication::notify(QObject *, QEvent *)                                          0x7ffff6fec87a 
    19 QCoreApplication::notifyInternal2(QObject *, QEvent *)                                 0x7ffff6fec9e0 
    20 ??                                                                                     0x7ffff70414fd 
    21 g_main_context_dispatch                                                                0x7ffff44587f7 
    22 ??                                                                                     0x7ffff4458a60 
    23 g_main_context_iteration                                                               0x7ffff4458b0c 
    24 QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>)             0x7ffff704104f 
    25 QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>)                                0x7ffff6fea9ca 
    26 QCoreApplication::exec()                                                               0x7ffff6ff313c 
    27 main                                                                       main.cpp 48 0x555555556488 
                                                                                      
    
    

    Thanks

    kshegunovK 1 Reply Last reply
    0
    • D Deckard

      Hi, I need to create QGuiApplication on the heap. I follow the example from
      https://doc.qt.io/qt-5/qapplication.html#details that creates QApplication in a separate function but in my function I want to return std::unique_ptr<QGuiApplication> instead of a raw QGuiApplication*.

      What I encountered are some strange looking errors depending on the way I create QGuiApplication.

      I've tried to create a minimal working program to show my problem:

      #include <memory>
      
      #include <QDebug>
      #include <QGuiApplication>
      
      
      std::unique_ptr<QGuiApplication> createApplication1(int argc, char *argv[])
      {
          // works
          std::unique_ptr<QGuiApplication> ptr(new QGuiApplication(argc,argv));
          return ptr;
      }
      
      
      std::unique_ptr<QGuiApplication> createApplication2(int argc, char *argv[])
      {
          // works
          std::unique_ptr<QGuiApplication> ptr;
          ptr.reset(new QGuiApplication(argc,argv));
          return ptr;
      }
      
      
      std::unique_ptr<QGuiApplication> createApplication3(int argc, char *argv[])
      {
          // app->exec() crashes randomly
          std::unique_ptr<QGuiApplication> ptr;
          QGuiApplication* app = new QGuiApplication(argc,argv);
          ptr.reset(app);
          return ptr;
      }
      
      
      std::unique_ptr<QGuiApplication> createApplication4(int argc, char *argv[])
      {
          // app->exec() always crashes
          return std::make_unique<QGuiApplication>(argc,argv);
      }
      
      
      int main(int argc, char *argv[])
      { 
          auto app = createApplication3(argc,argv);
      
          // auto app2 = std::make_unique<QGuiApplication>(argc,argv);
      
          // crashes with createApplication3 and createApplication4, but works with app2
          return app->exec();
      }
      

      The strange thing is the difference between createApplication2() and createApplication3() is minor (an addition of a named raw pointer) but the latter makes app->exec() crash randomly. Also, all these variants work when used directly in main() instead of a separate function, e.g. this works in main:

      auto app2 = std::make_unique<QGuiApplication>(argc,argv);
      

      but not in createApplication4().

      When the program crashes the stack trace is:

      1  __GI_raise                                                                 raise.c  58 0x7ffff5cd6fdf 
      2  __GI_abort                                                                 abort.c  89 0x7ffff5cd840a 
      3  __gnu_cxx::__verbose_terminate_handler()                                               0x7ffff65ee07d 
      4  ??                                                                                     0x7ffff65ec046 
      5  std::terminate()                                                                       0x7ffff65ec091 
      6  __cxa_throw                                                                            0x7ffff65ec2a9 
      7  qBadAlloc()                                                                            0x7ffff6dfe9b2 
      8  QListData::detach(int)                                                                 0x7ffff6e7cbba 
      9  ??                                                                                     0x7ffff6e284de 
      10 QCoreApplication::arguments()                                                          0x7ffff6fefd2f 
      11 ??                                                                                     0x7fffef97deb7 
      12 ??                                                                                     0x7fffef97ea04 
      13 _SmcProcessMessage                                                                     0x7fffef0eae45 
      14 IceProcessMessages                                                                     0x7fffeeeda33c 
      15 QMetaObject::activate(QObject *, int, int, void * *)                                   0x7ffff70185e9 
      16 QSocketNotifier::activated(int, QSocketNotifier::QPrivateSignal)                       0x7ffff70925ce 
      17 QSocketNotifier::event(QEvent *)                                                       0x7ffff7024ba2 
      18 QCoreApplication::notify(QObject *, QEvent *)                                          0x7ffff6fec87a 
      19 QCoreApplication::notifyInternal2(QObject *, QEvent *)                                 0x7ffff6fec9e0 
      20 ??                                                                                     0x7ffff70414fd 
      21 g_main_context_dispatch                                                                0x7ffff44587f7 
      22 ??                                                                                     0x7ffff4458a60 
      23 g_main_context_iteration                                                               0x7ffff4458b0c 
      24 QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>)             0x7ffff704104f 
      25 QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>)                                0x7ffff6fea9ca 
      26 QCoreApplication::exec()                                                               0x7ffff6ff313c 
      27 main                                                                       main.cpp 48 0x555555556488 
                                                                                        
      
      

      Thanks

      kshegunovK Offline
      kshegunovK Offline
      kshegunov
      Moderators
      wrote on last edited by
      #2

      You are passing a reference to a stack variable to QGuiApplication, which gets invalidated when you return from the function. Notice that argc should be passed as int & ... not that I have any idea why you would want to create the application object in the heap ...

      Read and abide by the Qt Code of Conduct

      1 Reply Last reply
      1
      • D Offline
        D Offline
        Deckard
        wrote on last edited by Deckard
        #3

        Thanks for your help kshegunov. Passing a reference to a local stack variable to QGuiApplication was indeed the source of the problem. I was misled by the fact that createApplication1() and createApplication2() worked flawlessly even with this error.

        "valgrind --leak-check=full" doesn't show anything, but valgrind isn't probably the best tool for stack-related errors . Maybe sanitizers could be helpful to detect this kind of bug.

        I'm creating an application with both Qt Widgets and Qt Quick Controls UI.

        My idea is to put both UIs into separate plugins which the main application starts. I was thinking about letting the plugins create a QGuiApplication / QApplication instance in a createApplication() function so the main app doesn't have to know the details (maybe it could even work with KApplication?).

        The alternative could be to create a QGuiApplication / QApplication in the main app based on the id (e.g. QString or enum) retrieved from the chosen plugin. This might have some limitations.

        Are there any better solutions?

        kshegunovK 1 Reply Last reply
        0
        • D Deckard

          Thanks for your help kshegunov. Passing a reference to a local stack variable to QGuiApplication was indeed the source of the problem. I was misled by the fact that createApplication1() and createApplication2() worked flawlessly even with this error.

          "valgrind --leak-check=full" doesn't show anything, but valgrind isn't probably the best tool for stack-related errors . Maybe sanitizers could be helpful to detect this kind of bug.

          I'm creating an application with both Qt Widgets and Qt Quick Controls UI.

          My idea is to put both UIs into separate plugins which the main application starts. I was thinking about letting the plugins create a QGuiApplication / QApplication instance in a createApplication() function so the main app doesn't have to know the details (maybe it could even work with KApplication?).

          The alternative could be to create a QGuiApplication / QApplication in the main app based on the id (e.g. QString or enum) retrieved from the chosen plugin. This might have some limitations.

          Are there any better solutions?

          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on last edited by
          #4

          @Deckard said in Creating QGuiApplication on the heap - crashes (multiple UIs):

          The alternative could be to create a QGuiApplication / QApplication in the main app based on the id (e.g. QString or enum) retrieved from the chosen plugin. This might have some limitations.

          Well, just creating one QApplication as one usually does should be just enough, QApplication is already QGuiApplication.

          Read and abide by the Qt Code of Conduct

          D 1 Reply Last reply
          0
          • kshegunovK kshegunov

            @Deckard said in Creating QGuiApplication on the heap - crashes (multiple UIs):

            The alternative could be to create a QGuiApplication / QApplication in the main app based on the id (e.g. QString or enum) retrieved from the chosen plugin. This might have some limitations.

            Well, just creating one QApplication as one usually does should be just enough, QApplication is already QGuiApplication.

            D Offline
            D Offline
            Deckard
            wrote on last edited by
            #5

            @kshegunov

            The documentation for QApplication:
            https://doc.qt.io/qt-5/qapplication.html#details
            says it depends on QtWidgets.

            I would like to avoid this in the Qt Quick version as it might ruin start-up time:)

            kshegunovK 1 Reply Last reply
            0
            • D Deckard

              @kshegunov

              The documentation for QApplication:
              https://doc.qt.io/qt-5/qapplication.html#details
              says it depends on QtWidgets.

              I would like to avoid this in the Qt Quick version as it might ruin start-up time:)

              kshegunovK Offline
              kshegunovK Offline
              kshegunov
              Moderators
              wrote on last edited by
              #6

              I don't follow, if you will have plugins that depend on widgets, then you will need the QtWidgets module (and by extension QApplication) anyway ... and you're complicating your life on a "might" ... doesn't make much sense to me.

              Read and abide by the Qt Code of Conduct

              D 1 Reply Last reply
              1
              • kshegunovK kshegunov

                I don't follow, if you will have plugins that depend on widgets, then you will need the QtWidgets module (and by extension QApplication) anyway ... and you're complicating your life on a "might" ... doesn't make much sense to me.

                D Offline
                D Offline
                Deckard
                wrote on last edited by Deckard
                #7

                @kshegunov

                I admit I'm not an expert so I may be wrong. I will try to explain my idea.

                Here is a simplified view of my application:
                alt text
                Link to the image:
                https://i.imgsafe.org/5e6f40aa3d.png
                https://s2.postimg.org/ei5411mkp/My_App.png

                The idea is that UI plugins are optional and only one is needed at the time. If I load ONLY MyAppQtQuick plugin, the QtWidgets will not get loaded (hopefully) because QGuiApplication that is created in MyAppQtQuick doesn't depend on QtWidgets.

                This will not be useful in Qt based environments like KDE or LXQt because QtWidgets are always loaded there but it might be useful in environments like GNOME where QtWidgets is not always loaded (because no other Qt application is running). So starting QtWidgets in addition to QtQuick will might affect start-up time in GNOME.

                There is also a packaging issue. The app will be free software and I'd like it to be packaged (hopefully) by distributors in way that allows the user selecting only needed plugins. Again, if someone is using GNOME and wants to use only MyAppQtQuick plugin, he can avoid downloading QtWidgets package if MyAppQtQuick creates QGuiApplication. But if I create QApplication in MyApp instead, then it will always depend on QtWidgets, whatever plugin is used.
                And for Android or other mobile systems QtWidgets are not useful.

                But you made me thinking if all plugins are not loaded anyway even I'm looking for only one with particular ID. This would be a common way of loading a particular plugin:

                MyPluginType* loadPlugin(const QString& pluginId)
                {
                    QDir dir ("/usr/lib/myapp");
                    
                    for (QString fileName : dir.entryList(QDir::Files))
                    {
                        auto path = dir.absoluteFilePath(fileName);
                        
                        QPluginLoader loader(path);
                        
                        QObject *somePlugin = loader.instance(); // loads a plugin; are plugin's dependencies loaded too?
                        
                        if (somePlugin)
                        {
                            if (auto myPlugin = qobject_cast<MyPluginType*>(somePlugin))
                            {
                                if ( myPlugin->name() == pluginId)
                                    return myPlugin;
                            }
                            
                            loader.unload(); // unloading a plugin
                        }
                    }
                    
                    return nullptr;
                }
                

                So if both plugins are installed and I want to load only a plugin with pluginId == "QtQuick" I will have to iterate over all files in the given folder, load them one by one to check if they have desired ID and unload them if not. QPluginLoader::instance() likely loads all plugin's dependencies.

                But the files in QDir::entryList() can be sorted in any order so MyAppQtWidgets plugin might be loaded (likely with its dependencies e.g. QtWidgets) before MyAppQtQuick plugin, only to discard it and unload.

                So to summarize: loading plugins selectively based on the retreived id is probably not the best idea because I have to load a plugin (with its dependencies) first to check its id. Another option would be to just blacklist or whitelist plugin file name but this may be error prone.

                What I'm writing may be completely wrong of course...


                EDIT: Ok, I've found something that looks like a good solution: I can get plugin's info without loading it using QPluginLoader::metaData().

                kshegunovK 1 Reply Last reply
                0
                • D Deckard

                  @kshegunov

                  I admit I'm not an expert so I may be wrong. I will try to explain my idea.

                  Here is a simplified view of my application:
                  alt text
                  Link to the image:
                  https://i.imgsafe.org/5e6f40aa3d.png
                  https://s2.postimg.org/ei5411mkp/My_App.png

                  The idea is that UI plugins are optional and only one is needed at the time. If I load ONLY MyAppQtQuick plugin, the QtWidgets will not get loaded (hopefully) because QGuiApplication that is created in MyAppQtQuick doesn't depend on QtWidgets.

                  This will not be useful in Qt based environments like KDE or LXQt because QtWidgets are always loaded there but it might be useful in environments like GNOME where QtWidgets is not always loaded (because no other Qt application is running). So starting QtWidgets in addition to QtQuick will might affect start-up time in GNOME.

                  There is also a packaging issue. The app will be free software and I'd like it to be packaged (hopefully) by distributors in way that allows the user selecting only needed plugins. Again, if someone is using GNOME and wants to use only MyAppQtQuick plugin, he can avoid downloading QtWidgets package if MyAppQtQuick creates QGuiApplication. But if I create QApplication in MyApp instead, then it will always depend on QtWidgets, whatever plugin is used.
                  And for Android or other mobile systems QtWidgets are not useful.

                  But you made me thinking if all plugins are not loaded anyway even I'm looking for only one with particular ID. This would be a common way of loading a particular plugin:

                  MyPluginType* loadPlugin(const QString& pluginId)
                  {
                      QDir dir ("/usr/lib/myapp");
                      
                      for (QString fileName : dir.entryList(QDir::Files))
                      {
                          auto path = dir.absoluteFilePath(fileName);
                          
                          QPluginLoader loader(path);
                          
                          QObject *somePlugin = loader.instance(); // loads a plugin; are plugin's dependencies loaded too?
                          
                          if (somePlugin)
                          {
                              if (auto myPlugin = qobject_cast<MyPluginType*>(somePlugin))
                              {
                                  if ( myPlugin->name() == pluginId)
                                      return myPlugin;
                              }
                              
                              loader.unload(); // unloading a plugin
                          }
                      }
                      
                      return nullptr;
                  }
                  

                  So if both plugins are installed and I want to load only a plugin with pluginId == "QtQuick" I will have to iterate over all files in the given folder, load them one by one to check if they have desired ID and unload them if not. QPluginLoader::instance() likely loads all plugin's dependencies.

                  But the files in QDir::entryList() can be sorted in any order so MyAppQtWidgets plugin might be loaded (likely with its dependencies e.g. QtWidgets) before MyAppQtQuick plugin, only to discard it and unload.

                  So to summarize: loading plugins selectively based on the retreived id is probably not the best idea because I have to load a plugin (with its dependencies) first to check its id. Another option would be to just blacklist or whitelist plugin file name but this may be error prone.

                  What I'm writing may be completely wrong of course...


                  EDIT: Ok, I've found something that looks like a good solution: I can get plugin's info without loading it using QPluginLoader::metaData().

                  kshegunovK Offline
                  kshegunovK Offline
                  kshegunov
                  Moderators
                  wrote on last edited by kshegunov
                  #8

                  Well, yes, there's that. But I still doubt the wisdom in delegating the responsibility to create the application to the plugins. You also run into the trouble of creating QObjects before QCoreApplication (by means of the plugin's QObject entry point) which is unsupported.

                  Read and abide by the Qt Code of Conduct

                  D 1 Reply Last reply
                  0
                  • kshegunovK kshegunov

                    Well, yes, there's that. But I still doubt the wisdom in delegating the responsibility to create the application to the plugins. You also run into the trouble of creating QObjects before QCoreApplication (by means of the plugin's QObject entry point) which is unsupported.

                    D Offline
                    D Offline
                    Deckard
                    wrote on last edited by
                    #9

                    @kshegunov

                    I understand that, without QCore/QGUI/QApplication, events and singals/slots don't work. But in the documentation for QObject, QCoreApplication, QGuiApplication, QApplication and QPluginLoader I haven't found any warning that creating QObjects before QCoreApplication is not supported, dangerous, illegal or leads to e.g. undefined behaviour. It is only recommended to create the application object as early as possible and QApplication must be created before any QPaintDevice objects, e.g. QWidgets. If I'm wrong, please correct me.

                    And if I'm wrong about this, another option is to split my application into two executables with different names, both dependent on different UIs. I wanted to avoid that because it adds some work to maintain separate files for each version for desktop environment / file manager integration.

                    kshegunovK 1 Reply Last reply
                    0
                    • D Deckard

                      @kshegunov

                      I understand that, without QCore/QGUI/QApplication, events and singals/slots don't work. But in the documentation for QObject, QCoreApplication, QGuiApplication, QApplication and QPluginLoader I haven't found any warning that creating QObjects before QCoreApplication is not supported, dangerous, illegal or leads to e.g. undefined behaviour. It is only recommended to create the application object as early as possible and QApplication must be created before any QPaintDevice objects, e.g. QWidgets. If I'm wrong, please correct me.

                      And if I'm wrong about this, another option is to split my application into two executables with different names, both dependent on different UIs. I wanted to avoid that because it adds some work to maintain separate files for each version for desktop environment / file manager integration.

                      kshegunovK Offline
                      kshegunovK Offline
                      kshegunov
                      Moderators
                      wrote on last edited by kshegunov
                      #10

                      In general, creating QObjects before the QApplication is not supported and can lead to weird crashes on exit, depending on the platform. This means static instances of QObject are also not supported. A properly structured single or multi-threaded application should make the QApplication be the first created, and last destroyed QObject.

                      From here and on the the mailing list. There are multiple posts for QObjects not working and/or crashing when created as static variables (i.e. before the application object) but I'm too lazy to dig them all up.

                      And if I'm wrong about this, another option is to split my application into two executables with different names, both dependent on different UIs.

                      As I said, just create one QApplication and roll with it. If you're so worried about the time it takes to initialize the widget stuff, benchmark it and only then decide if you need another solution. If you still insist on creating a separate application object for each UI, then pass an argument on startup and create the corresponding application object based on that.

                      Read and abide by the Qt Code of Conduct

                      D 1 Reply Last reply
                      0
                      • kshegunovK kshegunov

                        In general, creating QObjects before the QApplication is not supported and can lead to weird crashes on exit, depending on the platform. This means static instances of QObject are also not supported. A properly structured single or multi-threaded application should make the QApplication be the first created, and last destroyed QObject.

                        From here and on the the mailing list. There are multiple posts for QObjects not working and/or crashing when created as static variables (i.e. before the application object) but I'm too lazy to dig them all up.

                        And if I'm wrong about this, another option is to split my application into two executables with different names, both dependent on different UIs.

                        As I said, just create one QApplication and roll with it. If you're so worried about the time it takes to initialize the widget stuff, benchmark it and only then decide if you need another solution. If you still insist on creating a separate application object for each UI, then pass an argument on startup and create the corresponding application object based on that.

                        D Offline
                        D Offline
                        Deckard
                        wrote on last edited by Deckard
                        #11

                        @kshegunov

                        Ok, so I have no other choice then to create an application object first. Otherwise I will end up with a malfunctioning application.

                        Regarding the Qt Widgets dependency, I'd rather go with splitting my app into two parts. It's not about start up time - the difference may be negligible indeed.

                        It's about additional size (6.4 MiB on amd64 for Qt Widgets). If I understand correctly I have to deploy all needed Qt libs with my application for Android. So every time I update my app users have to also download all included Qt libs, including ~6.4 MiB for Qt Widgets which are redundant. On mobile devices it makes a difference - connection is slow, costly and drains battery, especially on 3G). Also, if all Qt-based apps are deployed that way they waste disk space.

                        Or, maybe I'm just oversensitive. Or wrong again:)

                        Yet another option would be a conditional, macro-based compilation to switch to QGuiApplication when compiling for Android. Maybe as a last resort...

                        Anyway, thank you very much for helping me out! Understanding the QApplication/QObject problem has been very important and saved me a frustration later in development.

                        kshegunovK 1 Reply Last reply
                        0
                        • D Deckard

                          @kshegunov

                          Ok, so I have no other choice then to create an application object first. Otherwise I will end up with a malfunctioning application.

                          Regarding the Qt Widgets dependency, I'd rather go with splitting my app into two parts. It's not about start up time - the difference may be negligible indeed.

                          It's about additional size (6.4 MiB on amd64 for Qt Widgets). If I understand correctly I have to deploy all needed Qt libs with my application for Android. So every time I update my app users have to also download all included Qt libs, including ~6.4 MiB for Qt Widgets which are redundant. On mobile devices it makes a difference - connection is slow, costly and drains battery, especially on 3G). Also, if all Qt-based apps are deployed that way they waste disk space.

                          Or, maybe I'm just oversensitive. Or wrong again:)

                          Yet another option would be a conditional, macro-based compilation to switch to QGuiApplication when compiling for Android. Maybe as a last resort...

                          Anyway, thank you very much for helping me out! Understanding the QApplication/QObject problem has been very important and saved me a frustration later in development.

                          kshegunovK Offline
                          kshegunovK Offline
                          kshegunov
                          Moderators
                          wrote on last edited by kshegunov
                          #12

                          @Deckard said in Creating QGuiApplication on the heap - crashes (multiple UIs via plugins):

                          So every time I update my app users have to also download all included Qt libs, including ~6.4 MiB for Qt Widgets which are redundant.

                          Why? Are you going to do static linking? If not what's the problem with only updating your app without updating the Qt binaries. Additionally, one of the very fine things I like about Qt is that it's binary compatible, which means you can even update the Qt binaries without deploying your app (assuming you don't use new-version features. This actually enables you to fetch patched Qt versions without modifying your app (or redeploying it).

                          if all Qt-based apps are deployed that way they waste disk space.

                          Well, the best way to deploy on Linux (I don't know much about android) is to not deploy Qt at all, but rather use the one from the distro's repository.

                          Yet another option would be a conditional, macro-based compilation to switch to QGuiApplication when compiling for Android. Maybe as a last resort...

                          You can setup this rather easily:

                          android-*: DEFINES += ANDROID_BUILD
                          else: QT += widgets
                          

                          in the pro file and then you can typedef the class in main (for brevity):

                          #ifdef ANDROID_BUILD
                          #include <QGuiApplication>
                          typedef QGuiApplication Application;
                          #else
                          #include <QApplication>
                          typedef QApplication Application;
                          #endif
                          
                          int main(int argc, char ** argv)
                          {
                              Application app(argc, argv);
                              return Application::exec();
                          }
                          

                          Read and abide by the Qt Code of Conduct

                          D 1 Reply Last reply
                          1
                          • kshegunovK kshegunov

                            @Deckard said in Creating QGuiApplication on the heap - crashes (multiple UIs via plugins):

                            So every time I update my app users have to also download all included Qt libs, including ~6.4 MiB for Qt Widgets which are redundant.

                            Why? Are you going to do static linking? If not what's the problem with only updating your app without updating the Qt binaries. Additionally, one of the very fine things I like about Qt is that it's binary compatible, which means you can even update the Qt binaries without deploying your app (assuming you don't use new-version features. This actually enables you to fetch patched Qt versions without modifying your app (or redeploying it).

                            if all Qt-based apps are deployed that way they waste disk space.

                            Well, the best way to deploy on Linux (I don't know much about android) is to not deploy Qt at all, but rather use the one from the distro's repository.

                            Yet another option would be a conditional, macro-based compilation to switch to QGuiApplication when compiling for Android. Maybe as a last resort...

                            You can setup this rather easily:

                            android-*: DEFINES += ANDROID_BUILD
                            else: QT += widgets
                            

                            in the pro file and then you can typedef the class in main (for brevity):

                            #ifdef ANDROID_BUILD
                            #include <QGuiApplication>
                            typedef QGuiApplication Application;
                            #else
                            #include <QApplication>
                            typedef QApplication Application;
                            #endif
                            
                            int main(int argc, char ** argv)
                            {
                                Application app(argc, argv);
                                return Application::exec();
                            }
                            
                            D Offline
                            D Offline
                            Deckard
                            wrote on last edited by
                            #13

                            @kshegunov

                            Yes, I know that on Linux package managers will install dependencies automatically, however I was worried about Android,

                            Fortunately there are two ways of deploying Qt-based apps for Android (blog post):

                            1. Using Ministro service, which will install needed Qt libs on demand. The libs are shared between applications. Ministro is available at Google Play and F-Droid.

                            2. Packaging Qt libs and app in the APK.

                            But it's too early for me to decide which one to choose.

                            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