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. Correctly terminating continuous, threaded application
Forum Updated to NodeBB v4.3 + New Features

Correctly terminating continuous, threaded application

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 3 Posters 1.0k 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.
  • P Offline
    P Offline
    prex
    wrote on last edited by
    #1

    I have a QGUIApplication/ QQmlApplicationEngine and a continuously running QThread. The QThread is the interface between the GUI and hardware (a ROS node). Since the GUI and the QThread are always necessary, I'm wondering how to terminate both of them correctly in case one of them is terminated. I'm thinking about two situations:

    1. I close the main window and the thread should also be terminated
    2. The thread crashes or is terminated (e.g. Ctrl+Z in terminal) and this should also terminate the GUI application

    So what I did up to now:

    First case:

    My QThread has the following destructor:

    QROSNode::~QROSNode() {
        if(ros::isStarted()) {
            ros::shutdown(); // this allows ros::spin() to quit and finish run()
            ros::waitForShutdown();
        }
        wait(); 
    }
    

    Are the QThreads terminated like normal class objects and the destructor called if the main application is stopped? Why is 'wait()' needed and is it the correct way?

    Second case:

    This is my main() function:

    int main(int argc, char *argv[])
    {
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    
    QGuiApplication app(argc, argv); // init application
    
    ros_node::QThread qthread(argc, argv); // create ROS node thread
    
    QQmlApplicationEngine engine;
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    
    engine.load(url);
    
    return app.exec(); // execute event loop
    }
    

    How can I shut down the main application if the QThread is terminated? Can I emit a signal in the QThread destructor which somehow terminates my main application?

    J.HilkJ 1 Reply Last reply
    1
    • P prex

      I have a QGUIApplication/ QQmlApplicationEngine and a continuously running QThread. The QThread is the interface between the GUI and hardware (a ROS node). Since the GUI and the QThread are always necessary, I'm wondering how to terminate both of them correctly in case one of them is terminated. I'm thinking about two situations:

      1. I close the main window and the thread should also be terminated
      2. The thread crashes or is terminated (e.g. Ctrl+Z in terminal) and this should also terminate the GUI application

      So what I did up to now:

      First case:

      My QThread has the following destructor:

      QROSNode::~QROSNode() {
          if(ros::isStarted()) {
              ros::shutdown(); // this allows ros::spin() to quit and finish run()
              ros::waitForShutdown();
          }
          wait(); 
      }
      

      Are the QThreads terminated like normal class objects and the destructor called if the main application is stopped? Why is 'wait()' needed and is it the correct way?

      Second case:

      This is my main() function:

      int main(int argc, char *argv[])
      {
      QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
      
      QGuiApplication app(argc, argv); // init application
      
      ros_node::QThread qthread(argc, argv); // create ROS node thread
      
      QQmlApplicationEngine engine;
      const QUrl url(QStringLiteral("qrc:/main.qml"));
      QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                       &app, [url](QObject *obj, const QUrl &objUrl) {
          if (!obj && url == objUrl)
              QCoreApplication::exit(-1);
      }, Qt::QueuedConnection);
      
      engine.load(url);
      
      return app.exec(); // execute event loop
      }
      

      How can I shut down the main application if the QThread is terminated? Can I emit a signal in the QThread destructor which somehow terminates my main application?

      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by J.Hilk
      #2

      hi @prex and welcome

      Signals and Slots are also here you friend :)

      QApplication has a aboutToQuit signal, that should be emitted when you close your last open window (with default settings)

      Connect that to your thread and call quit on it.

      Same for your QThread. Connect the threads finished signal to QApplication's quitslot


      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.

      P 1 Reply Last reply
      4
      • J.HilkJ J.Hilk

        hi @prex and welcome

        Signals and Slots are also here you friend :)

        QApplication has a aboutToQuit signal, that should be emitted when you close your last open window (with default settings)

        Connect that to your thread and call quit on it.

        Same for your QThread. Connect the threads finished signal to QApplication's quitslot

        P Offline
        P Offline
        prex
        wrote on last edited by
        #3

        Hi J-Hilk and thanks for your response.

        QApplication has a aboutToQuit signal, that should be emitted when you close your last open window (with default settings)

        Connect that to your thread and call quit on it.

        Does this mean that if I don't call quit, the QThread continues running? Does quit() call my destructor since I need to shut down my interface correctly?

        Same for your QThread. Connect the threads finished signal to QApplication's quitslot

        Same for this one. If I quit the main application on the 'finished' signal, is the destructor of the QThread still executed properly?

        jsulmJ 1 Reply Last reply
        0
        • P prex

          Hi J-Hilk and thanks for your response.

          QApplication has a aboutToQuit signal, that should be emitted when you close your last open window (with default settings)

          Connect that to your thread and call quit on it.

          Does this mean that if I don't call quit, the QThread continues running? Does quit() call my destructor since I need to shut down my interface correctly?

          Same for your QThread. Connect the threads finished signal to QApplication's quitslot

          Same for this one. If I quit the main application on the 'finished' signal, is the destructor of the QThread still executed properly?

          jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @prex said in Correctly terminating continuous, threaded application:

          If I quit the main application on the 'finished' signal, is the destructor of the QThread still executed properly?

          Yes, because you allocated it on the stack.

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          P 1 Reply Last reply
          2
          • jsulmJ jsulm

            @prex said in Correctly terminating continuous, threaded application:

            If I quit the main application on the 'finished' signal, is the destructor of the QThread still executed properly?

            Yes, because you allocated it on the stack.

            P Offline
            P Offline
            prex
            wrote on last edited by
            #5

            @jsulm said in Correctly terminating continuous, threaded application:

            @prex said in Correctly terminating continuous, threaded application:

            If I quit the main application on the 'finished' signal, is the destructor of the QThread still executed properly?

            Yes, because you allocated it on the stack.

            Ok, thanks! But then I don't understand why I need to quit my thread explicitly if the main application is terminated and the object goes out of scope anyway.

            jsulmJ J.HilkJ 2 Replies Last reply
            0
            • P prex

              @jsulm said in Correctly terminating continuous, threaded application:

              @prex said in Correctly terminating continuous, threaded application:

              If I quit the main application on the 'finished' signal, is the destructor of the QThread still executed properly?

              Yes, because you allocated it on the stack.

              Ok, thanks! But then I don't understand why I need to quit my thread explicitly if the main application is terminated and the object goes out of scope anyway.

              jsulmJ Offline
              jsulmJ Offline
              jsulm
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @prex said in Correctly terminating continuous, threaded application:

              object goes out of scope anyway

              the objects yes, but not necessarily the thread which is handled by the object. It is always a good idea to terminate threads in a clean way.

              https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              3
              • P prex

                @jsulm said in Correctly terminating continuous, threaded application:

                @prex said in Correctly terminating continuous, threaded application:

                If I quit the main application on the 'finished' signal, is the destructor of the QThread still executed properly?

                Yes, because you allocated it on the stack.

                Ok, thanks! But then I don't understand why I need to quit my thread explicitly if the main application is terminated and the object goes out of scope anyway.

                J.HilkJ Offline
                J.HilkJ Offline
                J.Hilk
                Moderators
                wrote on last edited by J.Hilk
                #7

                @prex said in Correctly terminating continuous, threaded application:

                @jsulm said in Correctly terminating continuous, threaded application:

                @prex said in Correctly terminating continuous, threaded application:

                If I quit the main application on the 'finished' signal, is the destructor of the QThread still executed properly?

                Yes, because you allocated it on the stack.

                Ok, thanks! But then I don't understand why I need to quit my thread explicitly if the main application is terminated and the object goes out of scope anyway.

                I'm not so sure about that, I haven't checked the source code, so I behold judgment :)

                But it's good form anyway.
                Take a look at the official Thread Example

                https://doc.qt.io/qt-5/qthread.html#details

                Even so the Thread object should get cleaned up automatically (its a member variable on the stack) quit and wait are still called.


                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
                0
                • P Offline
                  P Offline
                  prex
                  wrote on last edited by
                  #8

                  So I added these two connections:

                  QObject::connect(&qrosnode, SIGNAL(finished()), &app, SLOT(quit()), Qt::QueuedConnection);
                  QObject::connect(&app, SIGNAL(aboutToQuit()), &qrosnode, SLOT(quit()), Qt::QueuedConnection); 
                  

                  Take a look at the official Thread Example

                  https://doc.qt.io/qt-5/qthread.html#details

                  Even so the Thread object should get cleaned up automatically (its a member variable on the stack) quit and wait are still called.

                  Should I use 'deleteLater()'? Why not just putting 'quit()' and 'wait()' in each QThread destructor?

                  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