QT中的信号与事件,多线程
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QT中的信号与事件,多线程相关的知识,希望对你有一定的参考价值。
参考技术A 当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,将想要处理的信号和自己的一个函数(槽函数(slot))绑定并处理这个信号。https://blog.csdn.net/maizousidemao/article/details/104199773
Qt信号槽-原理分析
信号与槽的连接方式
事件发生时,qt创建了一个代表它的对象,
一般的事件传递方式是调用virtual函数。可以把自己想做的处理写在当前函数,然后把其他的都传递给base类处理。
更通用的处理方式:
可以在事件处理之前先通过filter,阻止特定的event传递给target widget,通过installEventFilter和removeEventFilter控制。
用户可以自定义自己的事件,并生成一个实例,通过sendEvent()和postEvent()发送它们。
两种方式
原型:void QObject::moveToThread( QThread * targetThread )
改变该对象与线程之间执行的关系,并不改变谁拥有该对象,只是让该对象执行成员函数时利用了target thread。「在哪创建就属于哪」这句话放在任何地方都是适用的。
https://blog.csdn.net/czyt1988/article/details/64441443
多线程
一、什么是Qt消息循环
Qt消息循环,就是从一个队列中不断取出消息,并响应消息的过程。窗体的鼠标、键盘、输入法、绘制,各种消息,都来自于Qt的消息循环。以Windows操作系统为例,Qt接管Windows原生窗口消息,并翻译成Qt的消息,派发给程序下的各个子对象、子QWidget等,通过接管层,可以很好屏蔽不同平台之间的差异性,开发人员不需要关心Windows或者X11的消息的差异性,只需要搞清楚各个QEvent之间是什么含义。
最开始的Qt消息循环开始于QCoreApplication::exec()。用户创建出一个QCoreApplication,或者说更多情况下是QApplication,执行QCoreApplication::exec(),一个应用程序便开始了。QCoreApplication会不断从操作系统获取消息,并且分发给QObject。
如果没有消息循环,那么Qt的信号和槽无法完全使用,有些函数也无法正确执行。举个例子,通过QueuedConnection连接的信号,其实是将一个事件压入了消息循环,如果没有QCoreApplication::exec(),那么这个消息循环将永远无法派发到指定的对象。
二、什么是线程相关性
准确点来说,应该是指QObject的线程相关性。以Qt文档中的示意图来作说明:
当我们创建一个QObject时,它会与创建自己所在的线程绑定。它参与的消息循环,其实是它所在线程的消息循环,如上图所示。假如某个线程没有默认的QThread::exec(),那么该线程上的QObject则无法接收到事件。另外,如果两个不同线程的QObject需要相互通信,那么只能通过QueuedConnection的方式,异步通知对方线程,在下一轮消息循环处理QObject的消息。
QObject的线程相关性默认会和它的parent保持一致。如果一个QObject没有parent,那么可以通过moveToThread,将它的线程相关性切换到指定线程。
了解QObject的线程相关性非常重要,很多初学者常常分不清一个多线程中哪些QObject应该由主线程创建,哪些应该由工作线程创建,我的观点是,它参与哪个消息循环,就由哪个来创建。
正因为这样的特性,我们才可以理解什么叫做AutoConnection。通过AutoConnect连接的两个QObject,如果是在同一个线程,那么可以直接调用(DirectConnection),如果不是在同一个线程,那么就通过事件通知的方式(QueuedConnection)来调用。通过信号和槽、事件或者QueuedConnection方式来进行线程间的通讯,尤其是与UI线程通讯,永远是最优雅的方式之一。
以上是关于QT中的信号与事件,多线程的主要内容,如果未能解决你的问题,请参考以下文章
QT多线程及通过事件进行通信(通过自定义事件,然后QApplication::postEvent给主界面,我之前用的是信号槽)