4.Qt Quick快速入门之线程基础

[复制链接]

该用户从未签到

2380

主题

2433

帖子

9139

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
9139
QQ
跳转到指定楼层
楼主
发表于 2017-7-29 22:54:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

想要查看内容赶紧注册登陆吧!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

首先必须明确的是,Qt中的线程使用是相对复杂的,并不像C#中那么随意,特别是结合串口、网络编程等,使用时稍有不慎就会出问题,然后Qt里面经常出了问题就直接崩溃(这个真是谁用谁知道),所以如果在功能上用异步方式能做到其实就没必要自己去开线程,当然如果自己写的函数比较耗时(比如不断地循环做操作之类的)就无法避免使用线程了。

  Qt中一般将耗时操作单独放在一个类中实现,在主线程中创建类对象,然后将这个对象移到子线程中,主线程与子线程间的通信主要通过信号和槽实现。另外对象是在主线程中创建的,对象中的成员都属于主线程,在主、子线程中都可以直接访问,不过如果你把对象中的成员也移到子线程中,那么在主线程就不能直接访问这个成员了。

  下面是一个使用实例。

  1. class ThreadManager : public QObject
  2. {
  3.     Q_OBJECT
  4.     QThread workerThread;
  5. public:
  6.     ThreadManager();
  7.     ~ThreadManager();
  8.     MyWorker * worker;
  9. signals:
  10.     void start();
  11. public slots:
  12.     void emitstart();
  13.     void emitstop();

  14.     void printThreadId(int count);
  15. };
复制代码
  1. ThreadManager::ThreadManager()
  2. {
  3.     worker = new MyWorker();
  4.     worker->moveToThread(&workerThread);
  5.     connect(this,SIGNAL(start()),worker,SLOT(Start()));
  6.     connect(worker,SIGNAL(invokeParentThreadMethod(int)),this,SLOT(printThreadId(int)));
  7.     workerThread.start();
  8. }

  9. ThreadManager::~ThreadManager()
  10. {
  11.     workerThread.quit();
  12. }

  13. void ThreadManager::emitstart()
  14. {
  15.     emit start();
  16. }

  17. void ThreadManager::emitstop()
  18. {
  19.     worker->stoped = true;
  20.     qDebug()<<"停止";
  21. }

  22. void ThreadManager::printThreadId(int count)
  23. {
  24.     //worker->stoped = true;
  25.     qDebug()<<QThread::currentThreadId()<<"\t"<<count;
  26. }
复制代码

ThreadManager 用来开启一个新的线程,然后在这个线程里面执行其他操作,下面是执行操作的类 MyWorker。

  1. class MyWorker : public QObject
  2. {
  3.     Q_OBJECT
  4. public:
  5.     explicit MyWorker(QObject *parent = 0);
  6.     bool stoped;
  7. signals:
  8.     void invokeParentThreadMethod(int count);
  9. public slots:
  10.     void Start();
  11. };
复制代码
  1. MyWorker::MyWorker(QObject *parent) :
  2.     QObject(parent)
  3. {
  4.     stoped = false;
  5. }

  6. void MyWorker::Start()
  7. {
  8.     int count =0;
  9.     stoped = false;
  10.     while(!stoped)
  11.     {
  12.         qDebug()<<QThread::currentThreadId()<<"\t"<<count++;
  13.         emit invokeParentThreadMethod(count);
  14.         QThread::msleep(500);
  15.     }
  16. }
复制代码

再看看我们在主线程中如何使用的

  1. QObject* win = engine.rootObjects()[0];
  2.     QObject* Button_Start = win->findChild<QObject*>("Button_Start");
  3.     QObject* Button_Stop = win->findChild<QObject*>("Button_Stop");

  4.     ThreadManager* therad = new ThreadManager();
  5.     QObject::connect(Button_Start,SIGNAL(clicked()),therad,SLOT(emitstart()));
  6.     QObject::connect(Button_Stop,SIGNAL(clicked()),therad,SLOT(emitstop()));
复制代码

这里只是一个很简单的线程使用示例,在串口、网络编程时往往涉及到线程同步、资源共享、线程通信等问题,比如子线程还在使用资源主线程却将资源释放了或是线程间通信时传过去的数据发生了变化等等,具体情况只有结合自己经验去分析了。


分享到:  QQ好友和群QQ好友和群
收藏收藏
回复

使用道具 举报

快速回复高级模式
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表