在 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. 在FMX中实现PostMessage的方法

    在FMX中实现PostMessage的方法 http://www.qdac.cc/?p=1090 2014-10-31 • Android.C++ Builder.Delphi.杂谈 • 4条评论 • ...

  2. Silverlight信息加密 - 通过Rfc2898DeriveBytes类使用基于HMACSHA1的伪随机数生成器实现PBKDF2

    原文: http://blog.csdn.net/xuyue1987/article/details/6706600 在上一篇文章当中,介绍到了通过Silverlight获取web.config中的值 ...

  3. 如何允许外网可以连接mysql数据库

    1.首先检查mysql所在服务器的防火墙,如果限制了外网对3306端口的连接,那么放开限制Linux服务器中执行 iptables -L   可以查看当前的防火墙规则iptables -F   可以清 ...

  4. Poj2946-The Warehouse(bfs+哈希)

    题目我就不粘贴了... 题意:给出地图,最大8*8,出口用'E'表示,空地用'.'表示,数字表示此处有多少个箱子,主人公的起点应该是在有箱子的地方,他可以朝四个方向移动,但是只有两种方式 一种是他移动 ...

  5. 关于C++中覆盖,重载,隐藏的一点说明

    C++覆盖 重载 隐藏是三个经常容易混淆的概念 这里我们简单总结下: 1.重载的条件(编译时多态) a.同一个类中 b.函数名相同,参数不同(返回值不能作为重载的条件) c.与函数是否为虚函数无关 2 ...

  6. 《Java程序员面试笔试宝典》之Static关键字有哪些作用

    static关键字主要有两种作用:第一,只想为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关.第二,希望某个方法或属性与类而不是对象关联在一起,也就是说,在不创建对象的情况下就可以通过 ...

  7. UGUI 过渡动画插件,模仿NGUI的Tween (转载)

    最近在相亲,后来好朋友跟我说他写了一个好插件,于是我就把女朋友甩了,看看他的插件,可以在UGUI制作简单过渡动画. 我看了下是模仿NGUI的Tween, 我在筱程的基础上稍微改到人性化, 简单支持的让 ...

  8. Kafka的Producer以及Consumer远程调用问题

    公司需要分布式的JMS,所以研究了Kafka,之前在本地都没有出现问题,但是在服务器上布Kafka的时候发现了消费者无法消费的问题. kafka布到一台服务器上面,由于业务原因,producer和ka ...

  9. Myeclipse安装破解

  10. xtrabackup备份恢复测试

    http://blog.chinaunix.net/uid-20682026-id-3319204.html