Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 每当COM事件发生时,如何更新自定义图形项(在pyqtgraph中)?_Python_Pyqtgraph - Fatal编程技术网

Python 每当COM事件发生时,如何更新自定义图形项(在pyqtgraph中)?

Python 每当COM事件发生时,如何更新自定义图形项(在pyqtgraph中)?,python,pyqtgraph,Python,Pyqtgraph,我制作了一个程序,实时接收原油期货的每一笔交易信息。基本上,OnReceiveRealData在执行事务时执行,并调用real\u get方法。在该方法中,收集当前时间、价格和数量数据,并用它们制作字典。有更多的方法可以从这个实时流数据生成OHLC格式的数据,但我的问题是,无论何时调用real\u get方法,如何更新自定义图形项(烛台图) class COM_Receiver(QAxWidget): def __init__(self): super().__init_

我制作了一个程序,实时接收原油期货的每一笔交易信息。基本上,
OnReceiveRealData
在执行事务时执行,并调用
real\u get
方法。在该方法中,收集当前时间、价格和数量数据,并用它们制作字典。有更多的方法可以从这个实时流数据生成OHLC格式的数据,但我的问题是,无论何时调用
real\u get
方法,如何更新自定义图形项(烛台图)

class COM_Receiver(QAxWidget):
    def __init__(self):
        super().__init__()
        self._create_com_instance()

        self.list_items = ['CLF18']

        self.OnReceiveRealData.connect(self.real_get)
        self.OnEventConnect.connect(self._event_connect)

    def _create_com_instance(self):
        self.setControl("KFOPENAPI.KFOpenAPICtrl.1")

    def _event_connect(self, err_code):
        if err_code == 0:
            print("connected")
            self.real_set()
        else:
            print("disconnected")
        self.login_event_loop.exit()

    def connect(self):
        self.dynamicCall("CommConnect(1)")
        self.login_event_loop = QEventLoop()                                   
        self.login_event_loop.exec_()

    def real_set(self):
        self.dynamicCall("SetInputValue(str, str)", "itemCode", ';'.join(self.list_items))
        ret = self.dynamicCall("CommRqData(str, str, str, str)", "itemCurrent", "opt10005", "", "1001")

    def real_get(self, code, realtype, realdata):
        if realtype == 'itemCurrent':
            eventTime = ( datetime.utcnow() + timedelta(hours=2) )
            currentPrice = self.dynamicCall("GetCommRealData(str, int)", "itemCurrent", 140)
            currentVolume = self.dynamicCall("GetCommRealData(str, int)", "itemCurrent", 15)

            dic_current = {'eventTime':eventTime, 'currentPrice':currentPrice, 'currentVolume':currentVolume}  

            self.make_ohlc(self.plt, dic_current)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    c = COM_Receiver()
    c.connect()

    sys.exit(app.exec_())
我参考了这篇文章()并意识到,每当收到新数据时,我可以更新烛台,而无需删除和创建
CandlestickItem()
实例(我现在就是这样做的,它会消耗大量资源)

在本文中,我尝试创建一个CandlestickItem()实例,并使用
set\u data
方法对其进行更新,但是,除非我单击图表(plt=pg.plot()),否则它无法正常工作,也无法显示更新后的烛台。也就是说,如果我离开程序大约10分钟,图表不会显示任何差异,但一旦我单击图表,它会立即显示最后10分钟的所有新烛台。我希望它能实时显示新的烛台,即使我没有连续点击图表

COM\u Receiver
类中的
OnReceiveRealData
事件调用
real\u get
方法时,如何更新自定义图形项?我认为
item.set\u data(data=dic\u current)
应该在
real\u get
方法中运行,但到目前为止我所尝试的并没有达到我预期的效果

下面的来源是文章中烛台示例的全部来源

import pyqtgraph as pg
from pyqtgraph import QtCore, QtGui
import random

## Create a subclass of GraphicsObject.
## The only required methods are paint() and boundingRect() 
## (see QGraphicsItem documentation)
class CandlestickItem(pg.GraphicsObject):
    def __init__(self):
        pg.GraphicsObject.__init__(self)
        self.flagHasData = False

    def set_data(self, data):
        self.data = data  ## data must have fields: time, open, close, min, max
        self.flagHasData = True
        self.generatePicture()
        self.informViewBoundsChanged()

    def generatePicture(self):
        ## pre-computing a QPicture object allows paint() to run much more quickly, 
        ## rather than re-drawing the shapes every time.
        self.picture = QtGui.QPicture()
        p = QtGui.QPainter(self.picture)
        p.setPen(pg.mkPen('w'))
        w = (self.data[1][0] - self.data[0][0]) / 3.
        for (t, open, close, min, max) in self.data:
            p.drawLine(QtCore.QPointF(t, min), QtCore.QPointF(t, max))
            if open > close:
                p.setBrush(pg.mkBrush('r'))
            else:
                p.setBrush(pg.mkBrush('g'))
            p.drawRect(QtCore.QRectF(t-w, open, w*2, close-open))
        p.end()

    def paint(self, p, *args):
        if self.flagHasData:
            p.drawPicture(0, 0, self.picture)

    def boundingRect(self):
        ## boundingRect _must_ indicate the entire area that will be drawn on
        ## or else we will get artifacts and possibly crashing.
        ## (in this case, QPicture does all the work of computing the bouning rect for us)
        return QtCore.QRectF(self.picture.boundingRect())

app = QtGui.QApplication([])

data = [  ## fields are (time, open, close, min, max).
    [1., 10, 13, 5, 15],
    [2., 13, 17, 9, 20],
    [3., 17, 14, 11, 23],
    [4., 14, 15, 5, 19],
    [5., 15, 9, 8, 22],
    [6., 9, 15, 8, 16],
]
item = CandlestickItem()
item.set_data(data)

plt = pg.plot()
plt.addItem(item)
plt.setWindowTitle('pyqtgraph example: customGraphicsItem')


def update():
    global item, data
    data_len = len(data)
    rand = random.randint(0, len(data)-1)
    new_bar = data[rand][:]
    new_bar[0] = data_len
    data.append(new_bar)
    item.set_data(data)
    app.processEvents()  ## force complete redraw for every plot

timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(100)

## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()