最近在做vnpy的一些界面修改,里面很多要做内容就是按照Event事件,作为pyqt5信号,来触发信号槽函数。
简单介绍下pyqt5的信号和信号槽,信号是就是QtCore.pyqtSignal类的实实例对象。信号有个emit() 方法,当emit执行时候,相当于触发信号,激活对应的信号槽。信号槽就是对应函数,将会被操作。界面按钮点击或者屏幕双击,都是一些原生的信号事件,直接调用就是可以,至于更多相关内容可以网上找找资料。
我们这里说的是当VNPY的EVENT事件做为pyQT5信号,触发对应信号槽函数。
比如一笔的成交,在vnpy中定义好一个成交事件
EVENT_CTA_TRADE = 'eCtaTrade'
此时,这里在建立是对应的信号实例,参数类型是Event。然后把这个信号发送函数和event绑定,代码如下
signal_trade_strategy = QtCore.pyqtSignal(Event)
event_engine.register(
EVENT_CTA_TRADE, signal_trade_strategy.emit
)
这个时候需要定义对应的信号槽,如果process_cta_trade_event是处理函数,定义如下
self.signal_trade_strategy.connect(process_cta_trade_event)
在处理函数中,Event 事件可以作为参数直接获取。之后可以做为内容更新
process_cta_trade_event(, event):
data = event.data
这里没有什么难点,如果信号槽事件不触及pyqt5 的UI 绘制的化,其实直接在EVENT绑定时候直接绑定信号槽函数。
但是如果信号槽事件涉及到UI绘制的化,必须要用自定义pyqt5信号,因为UI更新绘制是一个子线程,如果整个VNPY是作为子线程运行,比如用child模式,子线程定时触发运行,那么就会报错下面错误。唯一要注意地方。
QObject::connect: Cannot queue arguments of type 'QVector<int>'
(Make sure 'QVector<int>' is registered using qRegisterMetaType().)