打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
实战PyQt5: 103

创建自定义事件

虽然Qt内建了大量的事件类, 可以满足开发一个应用的绝大部分需求,但是有时候我们希望使用自定义事件来达到某个目的。实现自定义事件的步骤如下:

  • 创建一个继承自QEvent的类,例如: class MyEvent(QEvent)。
  • 定义事件类型(取值在QEvent.User和QEvent.MaxUser之间,建议使用registerEventType()函数自动创建一个全局唯一一个的事件类型,防止重复)。
  • 使用QCoreApplication的静态方法sendEvent()或postEvent()发送事件。
  • 在创建的类(比如:MyEvent)中重写event()或者customEvent()方法处理自定义事件。

发送事件有两种方法,一种是使用sendEvent()函数,一种是使用postEvent()函数。

1. sendEvent()函数: 该函数是阻塞式调用,它发送的对象事件,等待接收对象处理结束后才返回。其原型如下:

QCoreApplication.sendEvent(receiver : QObject, event : 'QEvent'),

参数:receiver为接收事件对象, event为传递的事件对象;

返回值:若事件被处理返回True,否则返回False。

2. postEvent()函数:该函数是异步调用,它向事件队列中登记一个指定接收者的事件,然后返回。 这种方法是线程安全的,因此它可以在多线程应用程序中用于在线程之间交换事件。其函数原型如下:

QCoreApplication.post(receiver: QObject, event: 'QEvent', priority: int = ...)

参数:receiver为接收事件对象; event为传递的事件对象;priority为优先级,其取值为枚举变量中Qt. EventPriority的值。

测试自定义事件

点击'生成自定义事件按钮’,在其中以postEvent()和sendEvent()两种方式发送自定义事件,从下面的输出信息可以看到,函数先处理了sendEvent()函数的事件,等事件循环运行时分发给当前对象后处理postEvent()事件。完整代码如下:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt, QEvent, QCoreApplication
from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton, 
                             QPlainTextEdit, QLabel, QVBoxLayout, 
                             QSpacerItem, QSizePolicy)
 
class CustomEvent(QEvent):
    #注册事件类型
    idType = QEvent.registerEventType()
    
    def __init__(self, data):
        super(CustomEvent, self).__init__(CustomEvent.idType)
        self.data = data
        
    def getData(self):
        return self.data
 
class DemoCustomEvent(QWidget):
    def __init__(self, parent=None):
        super(DemoCustomEvent, self).__init__(parent)   
        
         # 设置窗口标题
        self.setWindowTitle('实战PyQt5: 自定义事件演示')      
        # 设置窗口大小
        self.resize(400, 240)
      
        self.initUi()
        
    def initUi(self):
        mainLayout = QVBoxLayout()
        btnCreateEvent = QPushButton('生成自定义事件事件',self)
        btnCreateEvent.setMinimumHeight(40)
        btnCreateEvent.clicked.connect(self.onButtonCreateEvent)
        self.textBox = QPlainTextEdit(self)
        self.textBox.setReadOnly(True)
        mainLayout.addWidget(btnCreateEvent)
        #添加一段垂直间隔
        vSpacer = QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Fixed)
        mainLayout.addItem(vSpacer)
        #输出信息显示
        mainLayout.addWidget(QLabel('输出信息显示', self))
        mainLayout.addWidget(self.textBox)
        self.setLayout(mainLayout)
        
    def onButtonCreateEvent(self):
        # 使用PostEvent方式发送
        postEvent = CustomEvent('Post Custom Event')
        QCoreApplication.postEvent(self, postEvent)
        
        # 使用SendEvent方式发送
        sendEvent = CustomEvent('Send Custom Event')
        result = QCoreApplication.sendEvent(self, sendEvent)
        self.textBox.appendPlainText('发送事件结果是: {0}'.format(result))
        
    def customEvent(self, evt):
        if(evt.type() == CustomEvent.idType):
            self.textBox.appendPlainText('事件发送方式: {0}'.format(evt.getData()))
    
    '''    
    def event(self, evt):
        if(evt.type() == CustomEvent.idType):
            self.textBox.appendPlainText('事件发送方式: {0}'.format(evt.getData()))
            return True
        
        return super(DemoCustomEvent, self).event(evt)
    '''
    
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = DemoCustomEvent()
    window.show()
    sys.exit(app.exec()) 

运行效果如下图:

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
Qt事件和事件过滤器
qt 事件机制
Qt Event Dispatcher学习
QT 消息处理机制
[Qt] postevent emit
PyQt5快速入门(二)PyQt5信号槽机制
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服