QT的多线程编程方法

Qt 是一种基于 C++ 的跨平台 GUI 系统,能够提供给用户 构造图形用户界面的强 大功能。为了满足用户 构造复杂图形界面系统 的需求,Qt 提供了丰富的多线程编 程支持。Qt 主要从三个方面对多线 程编程提供支持:一、 构造了一些基本的与平 台无关的线程类;二、 提交用户自定义事件的 Thread-saf e 方式;三、多种线程间 同步机制,如信号量, 全局锁。本文着重讨论 Qt 中的多线程类及其多线 程通信方法,同时介绍 了QT在Linux和 WINDOWS平台下 多线程程序的编译方法
关键词:QT,QTE ,多线程通信,QT编 译,linux,wi ndows
一、 QT的线程类
在 Qt 系统中与线程相关的最 重要的类是 QThread 类,该类提供了创建一 个新线程以及控制线程 运行的各种方法。线程 是通过 QThread::r un() 重载函数开始执行的。
为编写出支持多线程的 程序,还需要实现两个 不同的线程对共有数据 的互斥访问,因此 Qt 还提供了 QMutex 类,一个线程在访问临 界数据时,需要加锁, 此时其他线程是无法对 该临界数据同时加锁的 ,直到前一个线程释放 该临界数据。通过这种 方式才能实现对临界数 据的原子操作。
二、 QT的线程间通
在 Qt 系统中,运行着一个G UI 主事件线程,这个主线 程从窗口系统中获取事 件,并将它们分发到各 个组件去处理。在 QThread 类中有一种从非主事件 线程中将事件提交给一 个对象的方法,也就是 QThread::p ostEvent() 方法,该方法提供了Q t 中的一种 Thread-saf e 的事件提交过程。提交 的事件被放进一个队列 中,然后 GUI 主事件线程被唤醒并将 此事件发给相应的对象 ,这个过程与一般的窗 口系统事件处理过程是 一样的。当事件处理过 程被调用时,是在主事 件线程中被调用的,而 不是在调用QThre ad::postEv ent 方法的线程中被调用。
1.、系统定义的事件 的提交
在 Qt 系统中,定义了很多种 类的事件,如定时器事 件、鼠标移动事件、键 盘事件、窗口控件事件 等。通常,事件都来自 底层的窗口系统。Qt 的主事件循环函数从系 统的事件队列中获取这 些事件,并将它们转换 为 QEvent,然后传 给相应的 QObjects 对象。
如下所示:
QWidget *mywidget;
void MyThread:: run()
{
   QThread::p ostEvent(M yWidget, new QPaintEven t(QRect(0, 0,100,100) ));
}
在MyThread线 程中发送重画事件给M yWidget窗体类
MyWidget的p aintEvent事 件响应会被自动调用, 用以响应MyThre ad发送过来的重画事 件。
void MyWidget:: paintEvent (QPaintEve nt*)
{
}
  2.、自定义事件 的提交
  为了满足用户的需 求,Qt 系统还提供了一个 QCustomEve nt 类,用于用户自定义事 件,这些自定义事件可 以利用 QThread::p ostEvent() 或者QApplica tion::post Event() 被发给各种控件或其他 QObject 实例,而 QWidget 类的子类可以通过 QWidget::c ustomEvent () 事件处理函数方便地接 收到这些自定义的事件 。需要注意的是:QC ustomEvent 对象在创建时都带有一 个类型标识 id 以定义事件类型,为了 避免与 Qt 系统定义的事件类型冲 突,该 id 值应该大于枚举类型 QEvent::Ty pe 中给出的 "User" 值。
  如下所示:
  UserEven t类是用户自定义的事 件类,其事件标识为3 46798,显然不会 与系统定义的事件类型 冲突。
  class UserEvent : public QCustomEve nt  //用户自定义的事件
  {
  public:
  UserEven t(QString s) : QCustomEve nt(346798) , sz(s) { ; }
  QString str() const { return sz; }
  private:
  QString sz;  
  };
  
  UserThre ad类是由QThre ad类继承而来的子类 ,在该类中除了定义有 关的变量和线程控制函 数外,最主要的是定义 线程的启动函数Use rThread::r un(),在该函数中 创建了一个用户自定义 事件UserEven t,并利用QThre ad类的postEv ent函数提交该事件 给相应的接收对象。
  class UserThread : public QThread    //用户定义的线程类
  {
  public:
  UserThre ad(QObject *r, QMutex *m, QWaitCondi tion *c);
  QObject *receiver;
  }
  void UserThread ::run()   //线程类启动函数, 在该函数中创建了一个 用户自定义事件
  {UserEve nt *re = new UserEvent( resultstri ng);
   QThread ::postEven t(receiver , re);
  }
  UserWidg et类是用户定义的用 于接收自定义事件的Q Widget类的子类 ,该类利用slotG o()函数创建了一个 新的线程recv(U serThread类 ),当收到相应的自定 义事件(即id为34 6798)时,利用c ustomEvent 函数对事件进行处理。
  void UserWidget ::slotGo()   //用户定义控件 的成员函数
  {mutex.l ock(); 
  if (! recv)
  recv = new UserThread (this, &mutex, &condition );
  recv->st art();
  mutex.un lock();
  }
  void UserWidget ::customEv ent(QCusto mEvent *e)  //用户自定义事件处 理函数
  {if (e->type() ==346798)
  {
  UserEven t *re = (UserEvent *) e;
      news tring = re->str();
    }
  }
  在这个例子中,U serWidget对 象中创建了新的线程U serThread, 用户可以利用这个线程 实现一些周期性的处理 (如接收底层发来的消 息等),一旦满足特定 条件就提交一个用户自 定义的事件,当Use rWidget对象收 到该事件时,可以按需 求做出相应的处理,而 一般情况下,User Widget对象可以 正常地执行某些例行处 理,而完全不受底层消 息的影响。
三、 QT多线程程序 的编译
先决条件:有编译成功 的多线程库 如libqt-mt. so(QT库)或 libqte-mt. so(QTE库)
   WINDOWS下:在 qconfig.h 文件中增加一个选项来 定义宏 QT_THREAD_ SUPPORT
Linux下:在ma kefile中的链接 选项中加入多线程库- lqt-mt或-lq te-mt,在编译选 项中增加-DQT_T HREAD_SUPP ORT 来增加线程支持宏 QT_THREAD_ SUPPORT。
本文来自互联网!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值