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. QThread delete on application close?

QThread delete on application close?

Scheduled Pinned Locked Moved Unsolved General and Desktop
2 Posts 2 Posters 314 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.
  • CJhaC Offline
    CJhaC Offline
    CJha
    wrote on last edited by CJha
    #1

    Hi, I am using the void QObject::moveToThread(QThread *targetThread) approach. My thread is not printing the debug output from its destructor on application close.

    MyThread class: h file

    class MyThread : public QThread
    {
    	Q_OBJECT
    
    public:
        const quint64 idx; // to keep a track of the number of threads created
        MyThread(); // to debug output on construction
        ~MyThread() override; // to debug output on destruction
    
    private:
        inline static quint64 count{0};
    };
    

    MyThread class: cpp file

    MyThread::MyThread() : idx{++count} { qDebug() << "MyThread" << idx; }
    
    MyThread::~MyThread() { qDebug() << "~MyThread" << idx; }
    

    MyObj class: h file

    class MyObj : public QObject
    {
        Q_OBJECT
    
    public:
        const quint64 idx; // to keep a track of the number of threads created
        MyObj();
        ~MyObj() override;
    
    public slots:
        void useMultiThreading(bool state);
    
    private:
        inline static quint64 count{0};
        QPointer<MyThread> myThread{nullptr};
    };
    

    MyObj class: cpp file

    MyObj::MyObj() : idx{++count}
    {
        qDebug() << "MyObj" << idx;
        myThread = new MyThread;
        connect(myThread, &QThread::finished, myThread, &QThread::deleteLater);
        this->moveToThread(myThread);
        myThread->start();
    }
    
    MyObj::~MyObj()
    {
        if(!myThread.isNull())
            myThread->quit();
        qDebug() << "~MyObj" << idx;
    }
    
    void MyObj::useMultiThreading(bool state)
    {
        if(state) {
            if(myThread.isNull()) {
                myThread = new MyThread;
                connect(myThread, &MyThread::finished, myThread, &MyThread::deleteLater);
                this->moveToThread(myThread);
                myThread->start();
            }
            else {
                if(this->thread() != myThread)
                    this->moveToThread(myThread);
                if(myThread->isFinished())
                    myThread->start();
            }
        }
        else {
            if(this->thread() != qApp->thread()) {
                this->moveToThread(qApp->thread());
                if(!myThread.isNull())
                    myThread->quit();
            }
        }
    }
    

    MainWindow: h file

    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget* parent = nullptr);
        ~MainWindow();
    
    signals:
        void useMultiThreading(bool state);
    
    private:
        Ui::MainWindowClass ui;
        QPointer<MyObj> myObj{nullptr};
    
    private slots:
        void on_useMultiThreading_chk_clicked(bool state);
        void on_useMyObj_chk_clicked(bool state);
    };
    

    MainWindow: cpp file

    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
    {
        ui.setupUi(this);
        myObj = new MyObj;
        connect(this, &MainWindow::useMultiThreading, myObj, &MyObj::useMultiThreading, Qt::QueuedConnection);
    }
    
    MainWindow::~MainWindow()
    {
        if(!myObj.isNull())
            myObj->deleteLater();
    }
    
    void MainWindow::on_useMultiThreading_chk_clicked(bool state) {emit useMultiThreading(state);}
    
    void MainWindow::on_useMyObj_chk_clicked(bool state)
    {
        if(state) {
            if(myObj.isNull()) {
                myObj = new MyObj;
                connect(this, &MainWindow::useMultiThreading, myObj, &MyObj::useMultiThreading, Qt::QueuedConnection);
            }
        }
        else {
            if(!myObj.isNull())
                myObj->deleteLater();
        }
    }
    

    The slot void MyObj::useMultiThreading(bool state) is connected to void MainWindow::useMultiThreading(bool state) as Qt::QueuedConnection. A checkbox in the main window sends the signal out.

    When I send out the signal useMultiThreading(false) the MyObj::myThread is deleted and prints the debug output in its destructor and if I send out signal useMultiThreading(true) and a new MyThread object is created and prints the debug output in its constructor.

    If I delete the myObj class object in my MainWindow it calls the destructor of MyThread class and the debug output from both classes destructors are printed. And if I create a new MyObj class object in my MainWindow then again the debug outputs in both MyObj and MyThread class constructors are printed.

    But on application close only the debug output from the destructor of MyObj class is printed, not from the MyThread class even if MyObj::myThread is not a nullptr. Why is this? Is my MyObj::myThread object getting destroyed properly on application close?

    Christian EhrlicherC 1 Reply Last reply
    0
    • CJhaC CJha

      Hi, I am using the void QObject::moveToThread(QThread *targetThread) approach. My thread is not printing the debug output from its destructor on application close.

      MyThread class: h file

      class MyThread : public QThread
      {
      	Q_OBJECT
      
      public:
          const quint64 idx; // to keep a track of the number of threads created
          MyThread(); // to debug output on construction
          ~MyThread() override; // to debug output on destruction
      
      private:
          inline static quint64 count{0};
      };
      

      MyThread class: cpp file

      MyThread::MyThread() : idx{++count} { qDebug() << "MyThread" << idx; }
      
      MyThread::~MyThread() { qDebug() << "~MyThread" << idx; }
      

      MyObj class: h file

      class MyObj : public QObject
      {
          Q_OBJECT
      
      public:
          const quint64 idx; // to keep a track of the number of threads created
          MyObj();
          ~MyObj() override;
      
      public slots:
          void useMultiThreading(bool state);
      
      private:
          inline static quint64 count{0};
          QPointer<MyThread> myThread{nullptr};
      };
      

      MyObj class: cpp file

      MyObj::MyObj() : idx{++count}
      {
          qDebug() << "MyObj" << idx;
          myThread = new MyThread;
          connect(myThread, &QThread::finished, myThread, &QThread::deleteLater);
          this->moveToThread(myThread);
          myThread->start();
      }
      
      MyObj::~MyObj()
      {
          if(!myThread.isNull())
              myThread->quit();
          qDebug() << "~MyObj" << idx;
      }
      
      void MyObj::useMultiThreading(bool state)
      {
          if(state) {
              if(myThread.isNull()) {
                  myThread = new MyThread;
                  connect(myThread, &MyThread::finished, myThread, &MyThread::deleteLater);
                  this->moveToThread(myThread);
                  myThread->start();
              }
              else {
                  if(this->thread() != myThread)
                      this->moveToThread(myThread);
                  if(myThread->isFinished())
                      myThread->start();
              }
          }
          else {
              if(this->thread() != qApp->thread()) {
                  this->moveToThread(qApp->thread());
                  if(!myThread.isNull())
                      myThread->quit();
              }
          }
      }
      

      MainWindow: h file

      class MainWindow : public QMainWindow
      {
          Q_OBJECT
      
      public:
          MainWindow(QWidget* parent = nullptr);
          ~MainWindow();
      
      signals:
          void useMultiThreading(bool state);
      
      private:
          Ui::MainWindowClass ui;
          QPointer<MyObj> myObj{nullptr};
      
      private slots:
          void on_useMultiThreading_chk_clicked(bool state);
          void on_useMyObj_chk_clicked(bool state);
      };
      

      MainWindow: cpp file

      MainWindow::MainWindow(QWidget *parent)
          : QMainWindow(parent)
      {
          ui.setupUi(this);
          myObj = new MyObj;
          connect(this, &MainWindow::useMultiThreading, myObj, &MyObj::useMultiThreading, Qt::QueuedConnection);
      }
      
      MainWindow::~MainWindow()
      {
          if(!myObj.isNull())
              myObj->deleteLater();
      }
      
      void MainWindow::on_useMultiThreading_chk_clicked(bool state) {emit useMultiThreading(state);}
      
      void MainWindow::on_useMyObj_chk_clicked(bool state)
      {
          if(state) {
              if(myObj.isNull()) {
                  myObj = new MyObj;
                  connect(this, &MainWindow::useMultiThreading, myObj, &MyObj::useMultiThreading, Qt::QueuedConnection);
              }
          }
          else {
              if(!myObj.isNull())
                  myObj->deleteLater();
          }
      }
      

      The slot void MyObj::useMultiThreading(bool state) is connected to void MainWindow::useMultiThreading(bool state) as Qt::QueuedConnection. A checkbox in the main window sends the signal out.

      When I send out the signal useMultiThreading(false) the MyObj::myThread is deleted and prints the debug output in its destructor and if I send out signal useMultiThreading(true) and a new MyThread object is created and prints the debug output in its constructor.

      If I delete the myObj class object in my MainWindow it calls the destructor of MyThread class and the debug output from both classes destructors are printed. And if I create a new MyObj class object in my MainWindow then again the debug outputs in both MyObj and MyThread class constructors are printed.

      But on application close only the debug output from the destructor of MyObj class is printed, not from the MyThread class even if MyObj::myThread is not a nullptr. Why is this? Is my MyObj::myThread object getting destroyed properly on application close?

      Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @CJha said in QThread delete on application close?:

      Why is this? Is my MyObj::myThread object getting destroyed properly on application close?

      Correct because of deleteLater(). I would guess the event loop is already gone when the second deleteLater() is called.

      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
      2

      • Login

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