实战PyQt5: 103-自定义事件


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

  • 创建一个继承自QEvent的类 , 例如: class MyEvent(QEvent) 。
  • 定义事件类型(取值在QEvent.User和QEvent.MaxUser之间 , 建议使用registerEventType()函数自动创建一个全局唯一一个的事件类型 , 防止重复) 。
  • 使用QCoreApplication的静态方法sendEvent()或postEvent()发送事件 。
  • 在创建的类(比如:MyEvent)中重写event()或者customEvent()方法处理自定义事件 。
发送事件有两种方法 , 一种是使用sendEvent()函数 , 一种是使用postEvent()函数 。
【实战PyQt5: 103-自定义事件】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 sysfrom PyQt5 import QtCore, QtGui, QtWidgetsfrom PyQt5.QtCore import Qt, QEvent, QCoreApplicationfrom 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 = http://kandian.youth.cn/index/datadef 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 Truereturn super(DemoCustomEvent, self).event(evt)'''if __name__ == '__main__':app = QApplication(sys.argv)window = DemoCustomEvent()window.show()sys.exit(app.exec())