尝试在PyQt5中打开PyQtGraph窗口

时间:2020-02-03 01:38:37

标签: python pyqt pyqtgraph

我的OptionsViz类正在单独工作。但是,当我放入异步内容时,它没有显示任何更新。为了简洁起见,我需要删除该代码,因此请不要使用循环。

import sys
import asyncio
from qasync import QEventLoop
from PyQt5.QtWidgets import QApplication, QMainWindow, QDockWidget

class OptionViz:
  def __init__(self, app):
    self.app = app
    self.p = pg.plot()
    self.p.setWindowTitle("pyqtgraph example: PlotSpeedTest")
    self.p.setRange(QtCore.QRectF(0, -10, 5000, 20))
    self.p.setLabel("bottom", "Index", units="B")
    self.curve = self.p.plot()

    self.data = np.random.normal(size=(50,5000))
    self.ptr = 0
    self.lastTime = time()
    self.fps = None

    timer = QtCore.QTimer()
    timer.timeout.connect(self.update)
    timer.start(0)

  def update(self):
      self.curve.setData(self.data[self.ptr%10])
      self.ptr += 1
      now = time()
      dt = now - self.lastTime
      self.lastTime = now
      if self.fps is None:
          fps = 1.0/dt
      else:
          s = np.clip(dt*3., 0, 1)
          self.fps = self.fps * (1-s) + (1.0/dt) * s
      self.p.setTitle('%0.2f fps' % fps)
      self.app.processEvents()  ## force complete redraw for every plot

async def main(app):
  # some await task here
  viz = OptionViz(app)
  # more await code here

if __name__ == '__main__':
  app = QApplication(sys.argv)
  loop = QEventLoop(app)
  asyncio.set_event_loop(loop)
  loop.create_task(main(app))
  loop.run_forever()

1 个答案:

答案 0 :(得分:1)

Qt与asyncio不兼容,因此已实现了多个库(例如quamash,asyncqt,qasync等)以使其兼容。对于quamash和asyncqt,它们有一个不允许执行的错误,但是qasync库使其无法解决(执行pip install qasync安装软件包)。

另一方面,由于无法执行main方法,因为它不执行耗时的任务,但它会立即执行,因此我不得不重组您的项目:

import sys
import asyncio
from qasync import QEventLoop
from PyQt5 import QtCore, QtWidgets
import pyqtgraph as pg
import numpy as np


class OptionViz:
    def __init__(self, app):
        self.app = app
        p = pg.plot()
        p.setWindowTitle("pyqtgraph example: PlotSpeedTest")
        p.setRange(QtCore.QRectF(0, -10, 5000, 20))
        p.setLabel("bottom", "Index", units="B")
        self.curve = p.plot()


async def main(viz):
    data = np.random.normal(size=(50, 5000))
    ptr = 0
    while True:
        viz.curve.setData(data[ptr % 10])
        await asyncio.sleep(0.1)
        ptr += 1


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    loop = QEventLoop(app)
    asyncio.set_event_loop(loop)
    viz = OptionViz(app)
    loop.create_task(main(viz))
    loop.run_forever()

同样,“ main”函数仅创建一个“ OptionViz”对象,该对象不会花费很长时间,因此在这种情况下使用异步是荒谬的。看来OP无法理解asyncio的操作。

通过重组代码,我们可以使该函数处于等待状态,以便OptionViz必须是QObject才能使用asyncSlot装饰器,此外QTimer必须是QObject的子代,以延长其生命周期。

import sys
import asyncio
from qasync import QEventLoop, asyncSlot
from PyQt5 import QtCore, QtWidgets
import pyqtgraph as pg
import numpy as np
from time import time


class OptionViz(QtCore.QObject):
    def __init__(self, app):
        super().__init__()
        self.app = app
        self.p = pg.plot()
        self.p.setWindowTitle("pyqtgraph example: PlotSpeedTest")
        self.p.setRange(QtCore.QRectF(0, -10, 5000, 20))
        self.p.setLabel("bottom", "Index", units="B")
        self.curve = self.p.plot()

        self.data = np.random.normal(size=(50, 5000))
        self.ptr = 0
        self.lastTime = time()
        self.fps = None

        timer = QtCore.QTimer(self)
        timer.timeout.connect(self.update)
        timer.start(0)

    @asyncSlot()
    async def update(self):
        self.curve.setData(self.data[self.ptr % 10])
        self.ptr += 1
        now = time()
        dt = now - self.lastTime
        self.lastTime = now
        if self.fps is None:
            fps = 1.0 / dt
        else:
            s = np.clip(dt * 3.0, 0, 1)
            self.fps = self.fps * (1 - s) + (1.0 / dt) * s
        self.p.setTitle("%0.2f fps" % fps)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    loop = QEventLoop(app)
    asyncio.set_event_loop(loop)
    viz = OptionViz(app)
    loop.run_forever()
相关问题