在 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. csdn的下载链接token

    qt之QComboBox定制 http://www.cnblogs.com/swarmbees/p/5710714.html http://download.csdn.net/detail/qq_30 ...

  2. Unix,windows和Mac中的换行

    Unix 系统里,每行结尾只有“<换行>”,即“\n”:Windows系统里面,每行结尾是“<换行><回车 >”,即“\r\n”:Mac系统里,每行结尾是“< ...

  3. java日期时间处理小结

    这两周时间的Java开发让我感觉到JAVA语言确实把一些简单的事情搞得很复杂,比如日期时间处理,或许是考虑不同时区国际化跨平台之类的因素,但JAVA语言处理确实让我很困惑,相信身边好多开发的同事也如此 ...

  4. unix c 07

    进程的结束函数 (exit._Exit)    exit 并不是立即退出,退出前执行 用atexit/on_exit函数 注册的函数.    exit(int status)中的status可以用 w ...

  5. NLog 2.0.0.2000 使用实例

    原文地址:http://www.cnblogs.com/sorex/archive/2013/01/31/2887174.html ---------------------------------- ...

  6. 《Two Days DIV + CSS》读书笔记——CSS控制页面方式

    1.1 你必须知道的知识 (其中包括1.1.1 DIV + CSS的叫法解释:1.1.2 DIV + CSS 名字的误区:以及1.1.3 W3C简介.由于只是背景知识,跳过该章.) 1.2 你必须掌握 ...

  7. MyWidget【简单自制控件】

    #coding=gbk from PyQt4 import QtGui,QtCore import random class MyWidget(QtGui.QWidget): def __init__ ...

  8. Linux基本操作 2-----Linux文件系统基本结构

    Linux的文件系统结构             Linux文件系统为一个倒转的单根树状结构 文件系统的根为"/" 文件系统严格区分大小写 路径使用“/”来分割,在windows使 ...

  9. 计算机图形学学习方法和相关书籍,做游戏,GIS,虚拟现实,三维引擎的都能够看看.

    本书參照<<图形学扫盲>> 整理的,原文内容引子: http://www.cppblog.com/lai3d/archive/2008/12/30/70796.html 前言: ...

  10. ECMAScript 6新特性介绍

    箭头函数 箭头函数使用=>语法来简化函数.在语句结构上和C#.Java 8 和 CoffeeScript相似,支持表达式和函数体. . =>`操作符左边为输入的參数.而右边则是进行的操作以 ...