c++多线程_C/C++编程笔记:Qt多线程功能简化方案

UI程序中经常有一些耗时的操作要处理,如果直接在UI线程中执行,整个界面都会卡住,出现无响应状态。
如果每次操作都生成一个线程类,而且相关数据都要传递过去,可能处理起来会比较麻烦!
因此本篇文章的初衷就是想简化这种情况。

f18e7fbcb00bdcaf60c26496568dfce9.png

仿照MFC方式解决

最开始我想到的就是按照MFC创建线程的方式进行解决。
通过类的 static 成员函数作为函数指针,通过QThread的run函数进行回调。
思路如下:

  • UI 部分大致逻辑如下
class Form : public QWidget{    Q_OBJECTpublic:     Form(QWidget *parent=0) : QWidget(parent)    {        ...        m_thread.setCallBack(run, this);        m_thread.start();    }...private:    void static run(QObject* obj)    {        Form*frm = (Form*) obj;        frm->todo();    }    void todo()    {         // 添加需要做的事情    }...private:    CThread m_thread;}
  • CThread实现方式如下
#ifndef CTHREAD_H#define CTHREAD_H#include // 函数指针定义,用于回调的;QObject *即为传递过来的 Form 的 this 对象指针typedef void (*pFuncPointer)(QObject *);   class CThread : public QThread{public:    CThread(QObject *obj=0):QThread(obj) {m_obj = obj;}    CThread(pFuncPointer func, QObject *obj):QThread(obj) {m_func = func; m_obj = obj;}    void setCallBack(pFuncPointer func, QObject *obj) {m_func = func; m_obj = obj;}    void setObj(QObject *obj) {m_obj = obj;}    void setFun(pFuncPointer func) {m_func = func;}private:    void run(){m_func(m_obj);}  // 回调函数,将 this 传递回去private:    pFuncPointer m_func;    QObject *m_obj;};#endif // CTHREAD_H

更进一步

由于我实在太懒了,觉得定义按照MFC那样的方式定义 static 成员函数 实在太麻烦了;
想直接一步到位,如果这样可以通过传递类的函数指针,这样就可以简化成下面这样!
思路如下:

  • UI 部分大致逻辑如下
class Form : public QWidget{    Q_OBJECTpublic:     Form(QWidget *parent=0) : QWidget(parent)    {        ...        m_thread.setCallBack(&MainForm::todo, this);  // 成员函数指针        m_thread.start();    }...private:    void todo()    {         // 添加需要做的事情    }...private:    CThread m_thread;}
  • CThread实现方式如下
#ifndef CTHREAD_H#define CTHREAD_H#include template                     // 模板class CThread : public QThread{public:    typedef void (T::*pFuncPointer)();   // 模板函数指针    CThread(T *obj=0):QThread(obj) {m_obj = obj;}    CThread(pFuncPointer func, T *obj):QThread(obj) {m_func = func; m_obj = obj;}    void setCallBack(pFuncPointer func, T *obj) {m_func = func; m_obj = obj;}    void setObj(T *obj) {m_obj = obj;}    void setFun(pFuncPointer func) {m_func = func;}private:    void run(){(m_obj->*m_func)();}  // 回调,这里的写法需要注意private:    pFuncPointer m_func;    T *m_obj;};#endif // CTHREAD_H

需要注意的地方

由于 todo 函数虽然是 Form 的成员函数,但是它是被另一个线程所调用的,所以它不属于UI线程。
在更新界面相关,或者需要更新界面信息时,可以在 Form 里面定义信号和对应的槽;
而且连接的时候,最好明确指明最后一个参数为Qt::QueuedConnection

总结


我的砖就抛到这里,希望对你们有用。
接下来的路就请各位小伙伴们自己走了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值