zoukankan      html  css  js  c++  java
  • Qt线程(1) moveToThread

    • 若在Qt准备使用线程类一般有两种方式(1) 采用WorkObject配合QThread进行使用 (2)继承QThread, 重载run()函数即可。
    • 注:采用Qt::Concurrent之类的不在本文讨论范围内.

      方式一、采用WorkObject配合QThread进行使用

    1. 创建一个用于计算的对象,该对象的运算相关函数防止在public slots 下:
       1 //..Object.h
       2 class CObject : public QObject
       3 {
       4     Q_OBJECT
       5 public:
       6     explicit CObject(QObject *parent = 0);
       7     ~CObject();
       8 
       9 signals:
      10     void sigFinish(const QString &s); //跨线程请注意使用const
      11 
      12 public slots:
      13     void Run();
      14     void Stop();
      15 
      16 private:
      17     bool m_bStop;
      18 };
      19 
      20 //..Object.cpp
      21 CObject::CObject(QObject *parent)
      22     : QObject(parent),m_bStop(false)
      23 {
      24 
      25 }
      26 
      27 void CObject::Run()
      28 {
      29     int i = 0;
      30     while(1)
      31     {
      32         if(m_bStop)
      33         {
      34             return;
      35         }
      36         qDebug()<<"Object TheradID = "<<QThread::currentThreadId();
      37         qDebug()<<"Run i = "<<i;
      38         sleep(1);
      39         if(++i == 10)
      40         {
      41             emit sigFinish("Finish");//信号是线程安全的,当然这得扯到后面的连接方式
      42         }
      43     }
      44 }
      45 
      46 void CObject::Stop()
      47 {
      48     m_bStop = true;
      49     emit sigFinish("Stop");//!!按照需求添加
      50 }
    2. 创建一个测试对象CTest
       1 //..test.h
       2 class CTest : public QObject
       3 {
       4     Q_OBJECT
       5 public:
       6     explicit CTest(QObject *parent = 0);
       7     void Run();
       8     void Stop();
       9 
      10 signals:
      11 
      12 private slots:
      13     void slotFinish(const QString &);
      14 
      15 private:
      16     QList<CObject *> m_ListObj;
      17 };
      18 
      19 //..test.cpp
      20 CTest::CTest(QObject *parent) : QObject(parent)
      21 {
      22 
      23 }
      24 
      25 void CTest::Run()
      26 {
      27     QThread *pThread = new QThread(this); // 只充当一个作为另个线程的入口
      28     CObject *pObj = new CObject; //注意:moveToThread不能使用在双亲对象上
      29     m_ListObj.append(pObj);
      30     
      31     qDebug()<<"Current Main Run Thread = "<<QThread::currentThreadId();
      32   
      33     connect(pObj,SIGNAL(sigFinish(QString)),pObj,SLOT(deleteLater())); 
      34     connect(pObj,SIGNAL(sigFinish(QString)),pThread,SLOT(quit()));
      35     connect(pObj,SIGNAL(sigFinish(QString)),this,SLOT(slotFinish(QString)));
      36     
      37     connect(pThread,SIGNAL(started()),pObj,SLOT(Run()));
      38     connect(pThread,SIGNAL(finished()),pObj,SLOT(deleteLater()));
      39     
      40      pObj->moveToThread(pThread);
      41 
      42     pThread->start();
      43 }
      44 void CTest::Stop()
      45 {
      46     foreach (CObject *pObj, m_ListObj)
      47     {
      48         if(!QMetaObject::invokeMethod(pObj,"Stop",Qt::DirectConnection))//!!留个坑,为什么autoConnection会没反应
      49         {
      50             qDebug()<<"error";
      51         }
      52     }
      53     m_ListObj.clear();
      54 }
      55 
      56 void CTest::slotFinish(const QString &s)
      57 {
      58     qDebug()<<"Main Thread Receive:"<<s;
      59 }
    3. main.cpp
       1 //..main.cpp
       2 int main(int argc, char *argv[])
       3 {
       4     QCoreApplication a(argc, argv);
       5     CTest test;
       6     test.Run();
       7     sleep(5);
       8     test.Stop();
       9     return a.exec();
      10 }
    4. 执行结果

      

      Well Done,方式2见Qt线程(2) QThread中使用WorkObject?

    祝:玩得愉快!
  • 相关阅读:
    第5章 JDBC/ODBC服务器
    第4章 SparkSQL数据源
    第3章 SparkSQL解析
    第2章 执行SparkSQL查询
    第1章 Spark SQL概述
    Ubutun重启网卡
    Java面试通关要点汇总整理
    40道Java基础常见面试题及详细答案
    ListView
    数据库表及字段命名规范
  • 原文地址:https://www.cnblogs.com/hejianglin/p/5246831.html
Copyright © 2011-2022 走看看