在 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. Solr简单部署

    因为公司最近涉及这个项目,想了解一下,以便提供更好的支持.. 参考URL: http://www.centoscn.com/CentosServer/test/2014/1127/4193.html ...

  2. Flash型单片机的加密与解密

    厂商利用单片机进行产品开发时,都会关心其代码和数据的保密性.考虑到用户在编写和调试代码时所付出的时间和精力,代码的成本是不言而喻的.    早期的单片机,代码是交给芯片制造商制成掩膜ROM.有两种加密 ...

  3. qt info.plist 添加

    http://www.waitingfy.com/archives/1242 http://www.sollyu.com/settings-icon-under-the-qt-mac-applicat ...

  4. QDialog 添加最大化、最小化按钮和关闭按钮,并且要正常显示

    在使用QDialog时,默认情况下只有“这是什么”和“关闭”按钮(不知道为什么QT要这么做),但是我们习惯有最大化和最小化按钮.本文介绍如何在该模式下如何设置. 新建一个QDialog工程,然后打开D ...

  5. c++ 05

    一.单例模式 二.成员指针 class Student { public:   string m_name;   void print (void) { ... } }; 1.指向成员变量的指针 成员 ...

  6. STL适配器的初步理解

    c++中的适配器有三种:容器适配器,迭代器适配器,函数适配器.下面一一介绍: 1.容器适配器:因为这些容器都是基于其他标准容器实现的所以叫做容器的适配器,具体的有stack,queue,priorit ...

  7. Java实现配置加载机制

    前言 现如今几乎大多数Java应用,例如我们耳熟能详的tomcat, struts2, netty…等等数都数不过来的软件,要满足通用性,都会提供配置文件供使用者定制功能. 甚至有一些例如Netty这 ...

  8. web前端之 CSS引入第三方插件

    引入第三方图标插件 - fontawesome 官网地址:http://fontawesome.io/ 1.下载图标插件包 下载地址:https://codeload.github.com/FortA ...

  9. 计算直线的交点数(set + 打表)

    计算直线的交点数 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  10. Hacker(12)----个人计算机安全防护策略

    了解了黑客的常用入侵方法,针对这些方法分别指定对应的防护策略不太现实,因此用户只能掌握个人计算机安全的常见防护策略,以确保计算机处在一个相对安全的环境中.常见个人计算机防护策略有:安装并及时升级杀毒软 ...