在 Qt 系统中,运行着一个GUI 主事件线程,这个主线程从窗口系统中获取事件,并将它们分发到各个组件去处理。在 QThread 类中有一种从非主事件线程中将事件提交给一个对象的方法,也就是 QThread::postEvent()方法,该方法提供了Qt 中的一种 Thread-safe 的事件提交过程。提交的事件被放进一个队列中,然后 GUI 主事件线程被唤醒并将此事件发给相应的对象,这个过程与一般的窗口系统事件处理过程是一样的。当事件处理过程被调用时,是在主事件线程中被调用的,而不是在调用QThread::postEvent 方法的线程中被调用。

1.、系统定义的事件的提交
在 Qt 系统中,定义了很多种类的事件,如定时器事件、鼠标移动事件、键盘事件、窗口控件事件等。通常,事件都来自底层的窗口系统。Qt 的主事件循环函数从系统的事件队列中获取这些事件,并将它们转换为 QEvent,然后传给相应的 QObjects 对象。
如下所示:
QWidget *mywidget;
void MyThread::run()
 {
   QThread::postEvent(MyWidget, new QPaintEvent(QRect(0,0,100,100)));
 }
在MyThread线程中发送重画事件给MyWidget窗体类。
MyWidget的paintEvent事件响应会被自动调用,用以响应MyThread发送过来的重画事件。
void MyWidget::paintEvent(QPaintEvent*)
{
}

  
2.、自定义事件的提交
  为了满足用户的需求,Qt 系统还提供了一个 QCustomEvent 类,用于用户自定义事件,这些自定义事件可以利用 QThread::postEvent() 或者QApplication::postEvent() 被发给各种控件或其他 QObject 实例,而 QWidget 类的子类可以通过 QWidget::customEvent() 事件处理函数方便地接收到这些自定义的事件。需要注意的是:QCustomEvent 对象在创建时都带有一个类型标识 id 以定义事件类型,为了避免与 Qt 系统定义的事件类型冲突,该 id 值应该大于枚举类型 QEvent::Type 中给出的 "User" 值。
  如下所示:
  UserEvent类是用户自定义的事件类,其事件标识为346798,显然不会与系统定义的事件类型冲突。
  class UserEvent : public QCustomEvent  //用户自定义的事件类
  {
  public:
  UserEvent(QString s) : QCustomEvent(346798), sz(s) { ; }
  QString str() const { return sz; }
  private:
  QString sz;  
  };
  
  UserThread类是由QThread类继承而来的子类,在该类中除了定义有关的变量和线程控制函数外,最主要的是定义线程的启动函数UserThread::run(),在该函数中创建了一个用户自定义事件UserEvent,并利用QThread类的postEvent函数提交该事件给相应的接收对象。
  class UserThread : public QThread   //用户定义的线程类
  {
  public:
  UserThread(QObject *r, QMutex *m, QWaitCondition *c);
  QObject *receiver;
  }
  void UserThread::run()   //线程类启动函数,在该函数中创建了一个用户自定义事件
  {UserEvent *re = new UserEvent(resultstring);
   QThread::postEvent(receiver, re);
  }
  UserWidget类是用户定义的用于接收自定义事件的QWidget类的子类,该类利用slotGo()函数创建了一个新的线程recv(UserThread类),当收到相应的自定义事件(即id为346798)时,利用customEvent函数对事件进行处理。
  void UserWidget::slotGo()  //用户定义控件的成员函数
  {mutex.lock(); 
  if (! recv)
  recv = new UserThread(this, &mutex, &condition);
  recv->start();
  mutex.unlock();
  }
  void UserWidget::customEvent(QCustomEvent *e)  //用户自定义事件处理函数
  {if (e->type()==346798) 
  {
  UserEvent *re = (UserEvent *) e;
      newstring = re->str();
    }
  }
  在这个例子中,UserWidget对象中创建了新的线程UserThread,用户可以利用这个线程实现一些周期性的处理(如接收底层发来的消息等),一旦满足特定条件就提交一个用户自定义的事件,当UserWidget对象收到该事件时,可以按需求做出相应的处理,而一般情况下,UserWidget对象可以正常地执行某些例行处理,而完全不受底层消息的影响。
   
 QT多线程程序的编译
先决条件:有编译成功的多线程库 如libqt-mt.so(QT库)或 libqte-mt.so(QTE库)
   WINDOWS下:在qconfig.h 文件中增加一个选项来定义宏 QT_THREAD_SUPPORT
Linux下:在makefile中的链接选项中加入多线程库-lqt-mt或-lqte-mt,在编译选项中增加-DQT_THREAD_SUPPORT 来增加线程支持宏 QT_THREAD_SUPPORT。
 
http://blog.csdn.net/yiyaaixuexi/article/details/6036820

QT---线程间通信(要先编译libqt-mt.so?)的更多相关文章

  1. C++多线程编程(三)线程间通信

    多线程编程之三——线程间通讯 作者:韩耀旭 原文地址:http://www.vckbase.com/document/viewdoc/?id=1707 七.线程间通讯 一般而言,应用程序中的一个次要线 ...

  2. java多线程与线程间通信

    转自(http://blog.csdn.net/jerrying0203/article/details/45563947) 本文学习并总结java多线程与线程间通信的原理和方法,内容涉及java线程 ...

  3. Net线程间通信的异步机制

    线程间通信 我们看下面的图 我们来看线程间通信的原理:线程(Thread B)和线程(Thread A)通信, 首先线程A 必须实现同步上下文对象(Synchronization Context), ...

  4. java线程基础巩固---线程间通信快速入门,使用wait和notify进行线程间的数据通信

    之前已经对于线程同步相关的知识点进行了详细的学习,这次来学习一下线程间的通信相关的知识,话不多说直接用代码进行演练,以一个简陋的生产者消费者模型来初步了解下线程间通信是怎么一回事. 生产消费者第一版: ...

  5. 2种方式(线程间通信/互斥锁)实现两个线程,一个线程打印1-52,另一个线程打印字母A-Z,打印顺序为12A34B56C......5152Z

    //2019/06/13 本周HT面试遇到的问题,答得不是很好,自己重新做一下.面试只需要写出线程间通信的方式,//我当时大致知道思路,因为之前看过马士兵老师的多线程视频,但是代码写出来估计编译都是报 ...

  6. 0038 Java学习笔记-多线程-传统线程间通信、Condition、阻塞队列、《疯狂Java讲义 第三版》进程间通信示例代码存在的一个问题

    调用同步锁的wait().notify().notifyAll()进行线程通信 看这个经典的存取款问题,要求两个线程存款,两个线程取款,账户里有余额的时候只能取款,没余额的时候只能存款,存取款金额相同 ...

  7. 线程间通信 GET POST

    线程间通信有三种方法:NSThread   GCD  NSOperation       进程:操作系统里面每一个app就是一个进程. 一个进程里面可以包含多个线程,并且我们每一个app里面有且仅有一 ...

  8. Java多线程编程核心技术---线程间通信(二)

    通过管道进行线程间通信:字节流 Java提供了各种各样的输入/输出流Stream可以很方便地对数据进行操作,其中管道流(pipeStream)是一种特殊的流,用于在不同线程间直接传送数据,一个线程发送 ...

  9. Java多线程编程核心技术---线程间通信(一)

    线程是操作系统中独立的个体,但这些个体如果不经过特殊处理就不能成为一个整体.线程间的通信就是成为整体的必用方案之一.线程间通信可以使系统之间的交互性更强大,在大大提高CPU利用率的同时还会使程序员对各 ...

  10. volatile关键字与线程间通信

    >>Java内存模型 现在计算机普遍使用多处理器进行运算,并且为了解决计算机存储设备和处理器的运算速度之间巨大的差距,引入了高速缓存作为缓冲,缓存虽然能极大的提高性能,但是随之带来的缓存一 ...

随机推荐

  1. SIM卡基础,各管脚意义,封装定义

    1. SIM简介 SIM卡(Subscriber Identity Module).即用户识别模块,是一张符合GSM规范的"智慧卡".SIM卡可以插入任何一部符合GSM规范的移动电 ...

  2. PowerShell_零基础自学课程_8_高级主题:WMI对象和COM组件

    本系列文章从最初的初识开始,基本上可以完成一些简单的系统管理了,为了更方便的管理系统,同时为了更好的发掘系统的性能,就需要用到系统提供 的一些高级特性,在Windows Server系列的OS中,如果 ...

  3. [科普]MinGW vs MinGW-W64及其它

    转载:http://tieba.baidu.com/p/3186234212?pid=54372018139&cid=#54372018139 这里也转一下吧. 部分参照备忘录原文: bitb ...

  4. Weekend counter

    Weekend counter Sofia has given you a schedule and two dates and told you she needs help planning he ...

  5. JavaEE连接池泄漏问题检测Oracle数据库

    1.项目环境 项目是典型的轻量级JavaEE项目,使用SSH框架构建,数据源使用DBCP管理,和Spring进行了整合. 项目数据库使用Oracle数据库. 项目DBCP配置内容如下 ###### D ...

  6. 处理emacs-org模式TODO的一个脚本

    处理前: 处理后: Table of Contents 1 前言 2 中文的处理 2.1 vim相关 2.2 perl 相关 3 时间相关 4 程序解析 1 前言 最近风帆问我一个问题,也就是处理or ...

  7. 需要考虑的9个SEO实践

    搜索引擎优化重要吗?我们知道,网站设计是把屏幕上平淡无奇变成令人愉快的美感,更直观地辨认信息.这也是人与人之间在沟通想法,这样的方式一直在演变. 穴居人拥有洞穴壁画,古埃及人有象形文字,现代人有网页设 ...

  8. Hdu4005-The war(双连通缩点)

    In the war, the intelligence about the enemy is very important. Now, our troop has mastered the situ ...

  9. VIm变成sublime (转)

    sublime在ubuntu下始终支持不是很好, 特别是对中文输入的支持,还有一些插件在ubuntu下也不能用. 在ubuntu下还是用vim吧.  我们一起把vim变成sublime. 只需要三步 ...

  10. (转)25个增强iOS应用程序性能的提示和技巧--高级篇

    高级当且仅当下面这些技巧能够解决问题的时候,才使用它们: 22.加速启动时间23.使用Autorelease Pool24.缓存图片 — 或者不缓存25.尽量避免Date格式化 高级性能提升 寻找一些 ...