1、使用QObject子类的movetothread方法 代替 QThread子类的run 实现多线程。
使用原始QThread对象的start方法启动线程==>连接原始QThread对象的started信号到QObject子类的槽(线程部分)。
 
2、有parent的object是不能moveToThread被移动到其他线程中的,所以还需要把子类对象给setParent(NULL)一下再moveToThread。
 
3、QObject子类对象在movetothread后,不要在线程中进行delete,因为QObject子类对象的内存管理还属于主线程。
 
4、QCoreApplication::exec()开启了主线程的事件循环。子线程也是一样,需要通过调用exec开启事件循环,否则事件不会分发给对对象。
QThread线程并不存在exec()函数。原因是exec()函数在QThread的run()中已经调用了。
 
5、postEvent: 可以给别的线程发送事件。事件会在目的对象所属的线程中运行。异步接口。
sendEvent: 仅用于同一个线程之间发送事件。目的对象必须与当前线程一样。同步接口
 
6、跨线程的事件传递可以通过 QCoreApplication::postEvent 和 重载QObject类的customEvent的方法 实现。
 
--------------------------------------------------------------------------------------------------------------------
 
1) 用原始的QThread的started信号触发自定义的slot启动线程(需要connect这个QThread对象的started信号),
而不是派生QThread的类重载run函数启动线程。
将一个类派生自QObject,然后实现所有的signal/slot,然后通过调用movetothread函数来使他们执行在新的线程里面,
而不是每次都要重新派生QThread,并且派生QThread的另外一个不好的地方是只有run函数内部的代码才会执行在新线程里面,
相比起来,派生QObject并使用movetothread函数更具有灵活性
 

2) 自定义对象(QObject子类)moveToThread进线程后,事件循环可以完全在此线程中运行。而它的内存管理应该还属于主线程。
有parent的object是不能moveToThread被移动到其他线程中的,所以还需要把子类对象给setParent(NULL)一下再moveToThread.
如下例子中(MyObject* myObj)被moveToThread进线程(QThread *thread),假如对象(MyObject* myObj)有父亲,它不能移动这种关系。
在另一个线程(而不是创建它的那个线程)中delete QObject对象是不安全的。除非你可以保证在同一时刻对象不在处理事件。
可以用QObject::deleteLater(),它会投递一个DeferredDelete事件,这会被对象线程的事件循环最终选取到。
 

3)exec的重要性。
主线程开始它的事件循环需要调用QCoreApplication::exec(), 子线程需要用QThread::exec(),功能基本是一样的,当然qt内部肯定是不同的实现。
假如没有事件循环运行,事件不会分发给对象。
举例来说,假如你在一个线程中创建了一个QTimer对象,但从没有调用过exec(),那么QTimer就不会发射它的timeout()信号.
对deleteLater()也不会工作。(这同样适用于主线程)。
 

4) 子线程接收事件
a) 如下例子中,子线程并不存在exec()函数。原因是exec()函数在QThread的run()中调用了。
我们这里并没有做一个QThread派生类,在run中调用exec()。因为我不推荐怎么干。原因很简单,并不需要这么干。
进一步说明是:qt提供的QThread已经完全满足线程创建的需要。为什么还要自己再画蛇添足呢。
b)本例子真正使用的是QCoreApplication::postEvent,和重载QObject类的customEvent的方法。消息一样会在(MyObject* myObj)所在的线程处理。
 

5) 关于QCoreApplication::postEvent和QCoreApplication::sendEvent
postEvent: 可以给别的线程发送事件。事件会在目的对象所属的线程中运行。这是一个异步接口
sendEvent: 仅用于同一个线程之间发送事件。目的对象必须与当前线程一样。这是一个同步接口。假如发送给属于另一个线程的对象,会报错:ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread a51f48. Receiver '' (of type
'MyObject') was created in thread a3bf18", file kernel\qcoreapplication.cpp, line 539
 
代码片段如下:(完整例子请到转载地址查看)
const QEvent::Type CustomEvent_Login = ( QEvent::Type )5001; //! 建议用5000以上唯一的标识

void MyObject::customEvent( QEvent *e )
{
    if ( e->type() == CustomEvent_Login ) //捕获消息
    {
        qDebug() << QString( "[%1]catch the event: %2!" )
                 .arg( ( qlonglong )QThread::currentThreadId() )
                 .arg( e->type() );
    }
}

int main( int argc, char *argv[] )
{
    QCoreApplication a( argc, argv );
    qDebug() << "main:" << ( qlonglong )QThread::currentThreadId();

//把业务逻辑对象设置进线程,不要把Qthread放进自己线程,这样的写法不建议。
    //绑定的时候最好设置QueuedConnection。这样就允许在myObj线程执行,否则可能会在主线程执行。
    //如果希望不要再子线程执行,用DirectConnection。
    MyObject *myObj = new MyObject;
    QThread *thread = new QThread();
    myObj->moveToThread( thread );
    thread->start();
    QObject::connect( thread, SIGNAL( started() ), myObj, SLOT( OnStartedSlot() ), Qt::QueuedConnection );

//定时器
    //MyObject::Started/MyObject::Timeout/都会在同一个子线程调用。
    QTimer *timer = new QTimer();
    QObject::connect( timer, SIGNAL( timeout() ), myObj, SLOT( OnTimeoutSlot() ), Qt::QueuedConnection );
    timer->start( 1000 );

//发送事件
    QCoreApplication::postEvent( myObj, new QEvent( CustomEvent_Login ) );
    qDebug() << QString( "[%1]send the event: %2!" )
             .arg( ( qlonglong )QThread::currentThreadId() )
             .arg( CustomEvent_Login );

return a.exec();
}

 
转载地址:http://blog.csdn.net/shaochat/article/details/41956707?utm_source=tuicool
http://blog.csdn.net/sonydvd123/article/details/8660624
 
 

对QT多线程以及事件投递的理解的更多相关文章

  1. Qt多线程学习-用例子来理解多线程(转),这个是我看过最好的文章,总结很详细(感觉exec()的作用就是保持线程不退出,这样方便随时处理主线程发来的信号,是一种非常别致的思路)good

    01 class MThread :public QThread 02 { 03 public: 04     MThread(); 05     ~MThread(); 06     virtual ...

  2. Qt多线程学习-用例子来理解多线程

    文章出处:DIY部落(http://www.diybl.com/course/3_program/c/c_js/20090303/157373_3.html) POINT 1:QThread类的实例与 ...

  3. QT虚拟小键盘设计--qt事件循环,事件发送的理解

    有人讲到QT5.7及其以后的版本才自带免费的小键盘插件. QT5.10中关于QKeyEvent类:点击打开链接 QT sendEvent和PostEvent, 点击打开链接 my god,我今天安装了 ...

  4. QT 多线程程序设计【转】

    QT通过三种形式提供了对线程的支持.它们分别是,一.平台无关的线程类,二.线程安全的事件投递,三.跨线程的信号-槽连接.这使得开发轻巧的多线程Qt程序更为容易,并能充分利用多处理器机器的优势.多线程编 ...

  5. Qt多线程编程总结(一)(所有GUI对象都是线程不安全的)

    Qt对线程提供了支持,基本形式有独立于平台的线程类.线程安全方式的事件传递和一个全局Qt库互斥量允许你可以从不同的线程调用Qt方法. 这个文档是提供给那些对多线程编程有丰富的知识和经验的听众的.推荐阅 ...

  6. QT 多线程程序设计(也有不少例子)

    QT通过三种形式提供了对线程的支持.它们分别是,一.平台无关的线程类,二.线程安全的事件投递,三.跨线程的信号-槽连接.这使得开发轻巧的多线程Qt程序更为容易,并能充分利用多处理器机器的优势.多线程编 ...

  7. QT 多线程程序设计 -互斥

    QT通过三种形式提供了对线程的支持.它们分别是,一.平台无关的线程类,二.线程安全的事件投递,三.跨线程的信号-槽连接.这使得开发轻巧的多线程Qt程序更为容易,并能充分利用多处理器机器的优势.多线程编 ...

  8. 【QT】 Qt多线程的“那些事”

    目录 一.前言 二.QThread源码浅析 2.1 QThread类的定义源码 2.2 QThread::start()源码 2.3 QThreadPrivate::start()源码 2.4 QTh ...

  9. 1.QT多线程使用小结

    开头 一个进程可以有一个或更多线程同时运行.线程可以看做是"轻量级进程",进程完全由操作系统管理,线程即可以由操作系统管理,也可以由应用程序管理. Qt 使用QThread来管理线 ...

随机推荐

  1. wait,waitpid

    要求 用man wait, man waitpid学习wait waitpid的使用 2 写出wait 的测试代码,要能说明你理解了wait 的返回值的每一位的含义 实验: ---------- ma ...

  2. jQuery 查找和过滤

    通常情况下选择器可以直接定位到我们想要的元素,但是,当我们拿到一个jQuery对象后,还可以以这个对象为基准,进行查找和过滤. 最常见的查找是在某个节点的所有子节点中查找,使用find()方法,它本身 ...

  3. web自动化测试-自动化测试模型介绍

    一.线性测试 什么是线性测试? 通过录制或编写对应用程序的操作步骤产生相应的线性脚本,每个测试脚本相对独立,不产生依赖和调用,单纯的来模拟用户完整的操作场景 缺点 1.开发成本高,测试用例之间存在重复 ...

  4. 微信小程序——获取当天的前一个月至后一个月

    看标题也不知道你有没有明白我想表达的意思,先上个动态图吧~ 需要分析: 1.获取当前日期的前一个月,后一个月和当月.比如说现在是7月5号,我需要得到6月5号至8月5号的日期,同时还要返回当前的星期. ...

  5. [51Nod 1222] - 最小公倍数计数 (..怎么说 枚举题?)

    题面 求∑k=ab∑i=1k∑j=1i[lcm(i,j)==k]\large\sum_{k=a}^b\sum_{i=1}^k\sum_{j=1}^i[lcm(i,j)==k]k=a∑b​i=1∑k​j ...

  6. SpringBoot学习(五)RSocket和Security

    一.RSocket RSocket是一个用于字节流传输的二进制协议.它通过在单个连接上传递异步消息来支持对称交互模型,主要支持的通讯层包括 TCP, WebSockets和Aeron(UDP). RS ...

  7. A Class of Blind Source Extraction Method Using Second-Order Statistics

    基于二阶统计量的盲源提取方法[1]. 文中提出了一系列基于二阶统计量的算法,包括离线BSE和在线BSE算法,可以提取平稳信号和非平稳信号.这些算法中,通过挖掘信号特征,提出了新的打分函数,以及一个无参 ...

  8. 【树形DP】骑士

    骑士 题目描述 \(Z\)国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬. 最近发生了一件可怕的事情,邪恶的\(Y\)国发动了一场针对Z国的侵略 ...

  9. python 安装离线库

    (起因:报错找不到一个module,百度也找不到这个module,机智如我找宁博翻墙看怎么解决,毕竟是歪果仁的代码嘛,果真就在git找到了这个module哈哈哈哈机智如我!) 方法: 进入命令行窗口, ...

  10. Healthcare in Azure