Qt的事件和与Widget跨线程交互
来源:互联网 发布:用g71编程内孔 编辑:程序博客网 时间:2024/06/10 02:40
一般gui的程序的模型总有至少两个主要线程,一个是界面的主事件循环所在的线程,另一个是处理工作任务的线程,工作线程看不见,在后台处理事务产生数据,然后显示在界面上。例如一个即时通讯客户端,主界面显示好友列表,工作线程接受来自网络的消息,收到消息后,要通知界面,将对应的好友的头像闪烁显示。这就要跨线程。
记得C#中有委托delegate,有InvokeRequired属性判断是否同线程操作,有Invoke来调用跨线程的委托。初学PySide,遇到同样的问题,看了半天文档,发现没有和C#类似的手段。但是,反倒可以用更有条理的方式来处理这样的跨线程调用请求,那就是事件。
QEvent是所有Qt事件的基类,构造函数只接受一个参数,那就是QEvent.Type类型的事件类型参数,如果是内置的事件类型,可以直接使用已定义的类型,例如QEvent.Close,它本质是一个int整数。如果要定义一个自己的事件,就需要一个这样的数字,而且和已有的所有事件类型不重复。
首先,使用QEvent.registerEventType这个静态方法来注册一个自己的类型,自定义的类型的值的返回是(QEvent.User, QEvent.UserMax)之间的一个数字,调用registerEventType时可以指定这样一个自己的数字,也可以不指定,由其自动分配一个数字。例如:
EVENT_INCOMING_MESSAGE = QEvent.registerEventType(QEvent.User + 0x01)
有了这个自己的类型,然后就是构建一个自己的事件类:
class IncomingMessageEvent(QEvent): def __init__(self, msg): super(IncomingMessageEvent, self).__init__( QEvent.Type(EVENT_INCOMING_MESSAGE) ) self.msg = msg
那么如何在工作线程中将该事件“投递”至窗口?可以使用QCoreApplication的postEvent方法,注意不是sendEvent,是postEvent,他们的区别就在于postEvent能跨线程“投递”,因为sendEvent是直接将事件送至目标Widget来处理,并返回处理结果,而postEvent是将事件插入处理队列之后返回,并不等待至事件获得实际处理。
假如app是主界面的一个QApplication对象,dlg是主界面的一个QDialog对象,msg是要投递的消息内容,那么将这个自己的事件投递至dlg的方法就是:
app.postEvent(dlg, IncomingMessageEvent(msg))
事件是投递完成,那么在QDialog中还得处理这个事件,不然dlg就要当SPAM来处理了...
所有Qt的Widget处理事件,都是由它的event方法来进行,所以只需要在自己的Widget中实现一个自己的event方法,该方法接受单个QEvent类型的参数。
class MainFrame(QDialog): # ...... def event(self, evt): if evt.type() == EVENT_INCOMING_MESSAGE: if hasattr(evt, 'msg'): msg = evt.msg self.show_incoming_message(msg) # 在界面显示该消息 return super(MainFrame, self).event(evt)
这时就可以安全的处理要显示的内容了。
- Qt的事件和与Widget跨线程交互
- Qt Widget重叠放置和兄弟Widget的事件传递
- Qt 的线程与事件循环
- Qt 的线程与事件循环
- Qt 的线程与事件循环
- Qt 的线程与事件循环
- Qt 的线程与事件循环
- Qt 的线程与事件循环
- Qt 的线程与事件循环
- Qt 的线程与事件循环
- Qt 的线程与事件循环
- Qt 的线程与事件循环
- Qt 的线程与事件循环
- [View] -- View与Controller和Widget交互
- qt中一个ui中的widget与另一个ui中的dialog之间的交互
- Qt中父子widget的事件传递
- Qt中父子widget的事件传递
- Qt线程、事件与QObject
- 开源 Android pdf 阅读器开发总结
- 持续集成IC
- 课程感想
- 编译qt5 examples里边的一个brower
- c++静态函数
- Qt的事件和与Widget跨线程交互
- 【Flex】使用ASDocs文档查看Label标签的所有可用样式
- linux下清除网卡ip
- UIView你知道多少
- HTML5资源地址
- HTML5 移动开发 -- Canvas 9.4 表格 , 折线图
- C# WinForm应用程序创建启动界面
- Winform编程基础之窗体单例模式和单线程操作
- android orm映射框架(类似hibernate)基本使用