找回密码
 立即注册
首页 业界区 安全 Qt moveToThread使用 <子线程定时器处理> ...

Qt moveToThread使用 <子线程定时器处理>

巨耗 2025-6-14 09:07:07
在进行桌面应用程序开发的时候,假设应用程序在某些情况下需要处理比较复杂的逻辑,如果只有一个线程去处理,就会导致窗口卡顿,无法处理用户的相关操作。
这种情况下就需要使用多线程,其中一个线程处理窗口事件,其他线程进行逻辑运算,多个线程各司其职,不仅可以提高用户体验还可以提升程序的执行效率。
Qt对多线程使用提供了多种方法,除了最简单的继承QThread,重写run函数外,还有一种比较常用且好用的方法:moveToThread
1.moveToThread理解

moveToThread允许用户自己封装一个“Worker”的类(Worker必须继承于QObject),
它可以将所有希望子线程处理的函数定义成自身的成员槽函数,通过信号槽方式,使其在子线程运行,且不影响主线程UI。
"Worker"类可以理解成一个“工作机”,它可以组合到任意一个有实际意义的类中,该工作机负责处理耗时的非UI工作。
2.实例使用

场景:在一个拥有定时测量功能的NIBP类中,由于包含许多高频定时器,需要将这些定时测量的定时器放在子线程中去做,防止测量过程中阻塞主线程UI
  1. // NIBP.h 文件
  2. class NIBP : public QObject
  3. {
  4. public:
  5.   void StartNoramlTest(); //开始测量
  6.   void EndTest(); //结束测量
  7. signals:
  8.     void SignalStartTest(); //开始测量信号
  9.     void SignalEndTest();   //结束测量信号
  10. private:
  11.   NIBPWorker *mWorker;
  12.   QThread *mWorkerThread;
  13. };
复制代码
"Worker"类的作用就是管理这些定时器,确保其在子线程创建且运行
  1. // NIBP.h 文件
  2. class NIBPWorker : public QObject  //一定要继承QObject
  3. {
  4.     Q_OBJECT
  5. public:
  6.     NIBPWorker();
  7.     void InitTimer();  //创建所有定时器
  8.     void StartWork();  //开启定时器
  9.     void EndWork();    //停止定时器
  10. private:
  11.     QTimer *mManualTimer;  //所有测量定时器
  12.     QTimer *mAutoTimer;
  13.     QTimer *mSTATTimer;
  14. };
复制代码
使用细节:
  1. // NIBP.cpp 文件
  2. //在NIBP类的构造函数中
  3. NIBPManager::NIBPManager()
  4. {
  5.     mWorker = new NIBPWorker;
  6.     mWorkerThread = new QThread;
  7.     mWorker->moveToThread(mWorkerThread); //初始化后,立刻将worker类移到创建的子线程中
  8.     connect(mWorkerThread, &QThread::started, mWorker, &NIBPWorker::InitTimer);   //在移入子线程后,就可以用connect执行"worker"中定义的槽函数
  9.     connect(this, &NIBPManager::SignalStartTest, mWorker, &NIBPWorker::StartWork);
  10.     connect(this, &NIBPManager::SignalEndTest, mWorker, &NIBPWorker::EndWork);
  11.     mWorkerThread->start();  //记得将子线程运行起来
  12. }
  13. void NIBPManager::StartNoramlTest()   //这些信号可以在主线程,或者其他线程中发,不影响worker中槽函数的执行
  14. {
  15.     emit SignalStartTest();
  16. }
  17. void NIBPManager::EndTest()
  18. {
  19.     emit SignalEndTest();
  20. }
复制代码
以上,"Worker"类组合在NIBP类中,负责处理高频定时器的测量任务,且不会影响主线程UI。
3.注意事项和总结

1."Worker"类继承QObject的原因,是因为moveToThread函数为QObject类的函数。
2.在moveToThread之前,"Worker"类所有的方法在主进程内运行,无论是直接调用还是通过信号和槽调用。
3.moveToThread之后,"Worker"类通过信号和槽系统调用的方法,都在子线程内运行;但是直接调用带来的所有工作都在主进程内发生。
4.moveToThread之后,是否start对方法在哪个线程内调用没有影响。
5."Worker"类构造和析构函数永远都在主线程内调用。
参数博客
moveToThread后成员函数到底在哪里运行
QT中QThread的各个方法,UI线程关系,事件关系详解

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册