非常感谢群主百忙之中的解答
signal.emit注册是有的,因为这个UI窗口是照搬“简单交易组件”来的,所以,注册机制跟MainWindow里的您写的那个手动下单一致
参考的源代码:
class TradingWidget(QtWidgets.QFrame):
"""简单交易组件"""
signal = QtCore.Signal(type(Event()))
......
#----------------------------------------------------------------------
def registerEvent(self):
"""注册事件监听"""
self.signal.connect(self.updateTick)
self.eventEngine.register(EVENT_TICK, self.signal.emit)
实际代码如下,这两个class的注册是一模一样的
class SniperTradingWidget(QtWidgets.QFrame):
"""狙击交易组件"""
signal = QtCore.Signal(type(Event()))
......
#----------------------------------------------------------------------
def registerEvent(self):
"""注册事件监听"""
self.signal.connect(self.updateTick)
self.eventEngine.register(EVENT_TICK, self.signal.emit)
至于调用这个class的上层函数,我也是参考’功能应用‘菜单的模板
’功能应用‘菜单源码,参考’打开配置编辑‘代码:
def createOpenAppFunction(self, appDetail):
"""创建打开应用UI的函数"""
def openAppFunction():
appName = appDetail['appName']
try:
self.widgetDict[appName].show()
except KeyError:
appEngine = self.mainEngine.getApp(appName)
# self.widgetDict[appName] = appDetail['appWidget'](appEngine, self.eventEngine)
# 无问西东,这部分细节实现还不太清楚,传递的参数不是(self.mainEngine, self.eventEngine, self.ctaEngine)
# 譬如CtaEngineManager(ctaEngine, eventEngine, parent=None)
self.widgetDict[appName] = appDetail['appWidget'](appEngine, self.eventEngine)
self.widgetDict[appName].show()
return openAppFunction
def openSettingEditor(self):
"""打开配置编辑"""
try:
self.widgetDict['settingEditor'].show()
except KeyError:
self.widgetDict['settingEditor'] = SettingEditor(self.mainEngine)
self.widgetDict['settingEditor'].show()
调用自编UI的代码(多传了一个ctaEngine,在初始化时的_init_里面就传入了):
def sniperTrade(self):
"""打开手动交易"""
try:
self.widgetDict['sniperTrade'].show()
except KeyError:
self.widgetDict['sniperTrade'] = SniperTradingWidget(self.mainEngine, self.eventEngine, self.ctaEngine) # 无问西东 新建窗体 新增传入ctaEngine
self.widgetDict['sniperTrade'].show()
自己写的updateTick函数内容也挺简单,也就是参考“简单交易组件”更新一下数据
def updateTick(self, event):
"""更新行情"""
tick = event.dict_['data']
if tick.vtSymbol != self.symbol:
return
self.tick = tick
updateStart = datetime.datetime.now()
self.ctaEngine.writeCtaLog(u'updateStart时间: %s' % (updateStart))
# 新增
self.lastTick = tick
self.getVolume() # 成交量相关计算函数
if not self.checkFixed.isChecked():
self.spinPrice.setValue(tick.lastPrice)
# priceTick = self.mainEngine.getContract(self.vtSymbol).priceTick
self.labelBidVolume1.setText(str(tick.bidVolume1))
self.labelAskVolume1.setText(str(tick.askVolume1))
self.labelBidPrice1.setText(str(tick.bidPrice1))
self.labelBidPrice2.setText(str(tick.bidPrice1 - 1 * self.priceTick))
self.labelBidPrice3.setText(str(tick.bidPrice1 - 2 * self.priceTick))
self.labelBidPrice4.setText(str(tick.bidPrice1 - 3 * self.priceTick))
self.labelBidPrice5.setText(str(tick.bidPrice1 - 4 * self.priceTick))
self.labelAskPrice1.setText(str(tick.askPrice1))
self.labelAskPrice2.setText(str(tick.askPrice1 + 1 * self.priceTick))
self.labelAskPrice3.setText(str(tick.askPrice1 + 2 * self.priceTick))
self.labelAskPrice4.setText(str(tick.askPrice1 + 3 * self.priceTick))
self.labelAskPrice5.setText(str(tick.askPrice1 + 4 * self.priceTick))
# 新增
self.labelBidPrice1Middle.setText(str(tick.bidPrice1))
self.labelAskPrice1Middle.setText(str(tick.askPrice1))
self.labelBidVolume1Middle.setText(str(tick.bidVolume1))
self.labelAskVolume1Middle.setText(str(tick.askVolume1))
self.labelAskVolumeLast.setText(str(self.askVolumeLast))
self.labelBidVolumeLast.setText(str(self.bidVolumeLast))
self.labelAskVolumeSum.setText(str(self.askVolumeSum))
self.labelBidVolumeSum.setText(str(self.bidVolumeSum))
# 偏移与点差计算挂单价格
self.labelAskpriceDiff.setText(str(tick.askPrice1 + self.spinDiff.value() * self.priceTick))
self.labelBidpriceDiff.setText(str(tick.bidPrice1 - self.spinDiff.value() * self.priceTick))
if tick.bidPrice2:
self.labelBidPrice2.setText(str(tick.bidPrice2))
self.labelBidPrice3.setText(str(tick.bidPrice3))
self.labelBidPrice4.setText(str(tick.bidPrice4))
self.labelBidPrice5.setText(str(tick.bidPrice5))
self.labelAskPrice2.setText(str(tick.askPrice2))
self.labelAskPrice3.setText(str(tick.askPrice3))
self.labelAskPrice4.setText(str(tick.askPrice4))
self.labelAskPrice5.setText(str(tick.askPrice5))
self.labelBidVolume2.setText(str(tick.bidVolume2))
self.labelBidVolume3.setText(str(tick.bidVolume3))
self.labelBidVolume4.setText(str(tick.bidVolume4))
self.labelBidVolume5.setText(str(tick.bidVolume5))
self.labelAskVolume2.setText(str(tick.askVolume2))
self.labelAskVolume3.setText(str(tick.askVolume3))
self.labelAskVolume4.setText(str(tick.askVolume4))
self.labelAskVolume5.setText(str(tick.askVolume5))
self.labelLastPrice.setText(str(tick.lastPrice))
if tick.preClosePrice:
rt = (tick.lastPrice/tick.preClosePrice)-1
self.labelReturn.setText(('%.2f' %(rt*100))+'%')
else:
self.labelReturn.setText('')
# 新增
self.askPricePrevious = self.lastTick.askPrice1
self.bidPricePrevious = self.lastTick.bidPrice1
self.volumePrevious = self.lastTick.volume
updateEnd= datetime.datetime.now()
self.ctaEngine.writeCtaLog(u'updateEnd时间: %s' % (updateEnd))
self.ctaEngine.writeCtaLog(u'update运行时间: %s' % (updateEnd - updateStart))
感觉定义class 和调用class 都跟原版很接近的呀?好像不是注册事件的原因,还有什么其他的可能性么?或者我的调用class有问题?它的现象是可以正常启动,也可以正常运行,只是运行一个小时左右,就出现UI(未响应)。
感谢群主的指导
补充:
因为在updateTick函数的开始 和结尾都打印了时间戳
查看log发现,最后的时间戳是成对出现的,也就是最后一次是顺利的运行到了updateTick的结尾,不是死在了这个函数的内部计算过程中
2019-07-30 10:33:51,516 INFO: CTA_STRATEGY updateStart时间: 2019-07-30 10:33:51.400000
2019-07-30 10:33:51,571 INFO: CTA_STRATEGY updateEnd时间: 2019-07-30 10:33:51.409000
2019-07-30 10:33:51,572 INFO: CTA_STRATEGY update运行时间: 0:00:00.009000