QT多线程使用

QT5以后官方推荐用moveToThread的方式实现多线程。

 


官方例子如下

class Worker : public QObject 
  {
      Q_OBJECT
    
//继承自QObject的工作类
  public slots:
      void doWork(const QString &parameter) {
          QString result;
          /* ... here is the expensive or blocking operation ... */
          emit resultReady(result);
      }

  signals:
      void resultReady(const QString &result);
  };

  class Controller : public QObject
  {
      Q_OBJECT
      QThread workerThread;
  public:
      Controller() {
          Worker *worker = new Worker;//实例化一个工作类
          worker->moveToThread(&workerThread);//移入到工作线程中
          connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);//工作线程结束就释放掉工作类实例
          connect(this, &Controller::operate, worker, &Worker::doWork);//工作类与主线程交互
          connect(worker, &Worker::resultReady, this, &Controller::handleResults);//工作类与主线程交互
          workerThread.start();
      }
      ~Controller() {
          workerThread.quit();
          workerThread.wait();
      }
  public slots:
      void handleResults(const QString &);
  signals:
      void operate(const QString &);
  };

这个实例有一个问题,当工作类任务结束后,无法结束工作线程释放资源,所以在工作类里加一个信号,当耗时操作完成后去通知主线程,在主线程中释放工作类和工作线程的资源。

修改一下如下:

class Worker : public QObject
{
    Q_OBJECT
public:
    ~Worker(){
        qDebug() << "Worker 析构";
    }
public slots:

    void doWork(QString parameter){
        //QString result;
        //emit resultReady(result);//工作类可以通过信号返回结果给控制类
        emit finished();//自定义的工作类结束信号
    }
signals:
    void resultReady(const QString &result);
    void finished();
};

class Controller : public QObject
{
    Q_OBJECT
    QThread workerThread;
public:
    explicit Controller(){
        Worker *worker = new Worker;
        worker->moveToThread(&workerThread);

        connect(&workerThread, &QThread::finished, this, &QObject::deleteLater);//delete工作类
        connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);//delete控制类

        //控制类和工作类通过信号和槽交互
        connect(this, &Controller::operate, worker, &Worker::doWork);
        connect(worker, &Worker::resultReady, this, &Controller::handleResults);
        connect(worker, &Worker::finished, [=]{
            workerThread.quit();
            workerThread.wait();
        });
        workerThread.start();
    }

    ~Controller(){
        qDebug() << "Controller析构";
    }

    void test(QString str){
        emit operate(str);
    }
public slots:
    void handleResults(QString str);
signals:
    void operate(QString str);
};

 

posted @ 2021-08-18 20:21  陈和权  阅读(195)  评论(1编辑  收藏  举报