2017-05-04 100 views
0

我一直在爲beagle骨黑的GUI工作,當點擊一個按鈕並開始通過SPI獲取數據時啓動一個線程。圖形用戶界面與pyqtgraph永不刷新

此函數位於名爲Scanner(QObject)的類中,並在單擊「開始」按鈕時在不同的線程中運行。

def scan (self): 
    thread_name = QThread.currentThread().objectName() 
    self.sig_msg.emit('Scanning '+thread_name) 
    for step in range(nsamples): 
     data = self.read_reg(reg[thread_name]) 
     self.sig_data.emit(step, data) 
     QThread.currentThread().msleep(50) 
     app.processEvents() 
     if self.__abort: 
      self.sig_msg.emit('scan stopped by user') 
      break 
    self.sig_done.emit(thread_name) 

sig_msg是一個pyqtsignal連接到GUI線程中的以下函數。

@pyqtSlot(int, int) 
def on_scaner_data(self, t: int, y: int): 
    app.processEvents() 
    self.debugBox.insertPlainText('t: '+str(t)+'y: '+str(y)+'\n') 
    self.debugBox.ensureCursorVisible() 
    self.MainGraph.update_fig(t,y) 

最後調用MainGraph.update_fig()。在那個函數裏面,我使用setData(self.datat,self.datay)和app.processEvents()來更新圖形,但是沒有任何變化。如果我運行情節(self.datat,self.datay)而不是重繪圖表,但會導致巨大的性能下降。

class DynamicPlotter(PlotWidget): 
def __init__(self,parent=None): 
    PlotWidget.__init__(self) 
    self.setParent(parent) 
    # Use getPlotItem() to get the PlotItem inside PlotWidget. 
    self.pitem = self.getPlotItem() 
    #now pitem is our PlotItem 
    self.pitem.curve=self.pitem.plot() 
    #curve is a new PlotDataItem added by PlotItem.plot() 
    self.datat = [1,2] 
    self.datay = [1,2] 
    self.pitem.curve.setData(self.datat,self.datay) 
    #this graph works fine 
    self.datat = [] 
    self.datay = []   
def update_fig(self,t:int,y:int):  
    self.datat.append(t) 
    self.datay.append(y) 
    #it works 
    self.pitem.curve=self.pitem.plot(self.datat,self.datay) 
    #it doesn't 
    self.pitem.curve.setData(self.datat,self.datay) 
    app.processEvents() 
    print (self.datat) 
    log.debug(str(t)+str(y)) 
def reset_figure(self): 
    log.debug('clean graph') 
    self.clear() 

我一直在關注pyqtplot中的這個例子,我的想法是在我的GUI中做類似的事情。

import initExample 
    from pyqtgraph.Qt import QtGui, QtCore 
    import numpy as np 
    import pyqtgraph as pg 
    from pyqtgraph.ptime import time 
    app = QtGui.QApplication([]) 
    p = pg.plot() 
    p.setWindowTitle('pyqtgraph example: PlotSpeedTest') 
    p.setRange(QtCore.QRectF(0, -10, 5000, 20)) 
    p.setLabel('bottom', 'Index', units='B') 
    curve = p.plot() 
    data = np.random.normal(size=(50,5000)) 
    ptr = 0 
    lastTime = time() 
    fps = None 
    def update(): 
     global curve, data, ptr, p, lastTime, fps 
     curve.setData(data[ptr%10]) 
     ptr += 1 
     now = time() 
     dt = now - lastTime 
     lastTime = now 
     if fps is None: 
      fps = 1.0/dt 
     else: 
      s = np.clip(dt*3., 0, 1) 
      fps = fps * (1-s) + (1.0/dt) * s 
     p.setTitle('%0.2f fps' % fps) 
     app.processEvents() ## force complete redraw 
    timer = QtCore.QTimer() 
    timer.timeout.connect(update) 
    timer.start(0) 

我一直在閱讀文檔,並知道我不知道哪裏是問題。我敢打賭,線程或事件循環處理程序,但我不知道。 哪些是我必須檢討的關鍵點? 任何線索?

謝謝。

+0

我建議您將'pyqtgraph'標記添加到您的帖子中。我會自己做,但你必須刪除另一個標籤(你可以有最多5個標籤)。 – titusjan

回答

1

經過一段時間,我發現自己的問題。 我修復了問題,改變了我用來重置圖形和停止掃描線程直到元素繪製的方式。

更改復位功能。 self.clear()刪除PlotWidget上的痕跡,這不是我所需要的。

def reset_figure(self): 
    log.debug('clean graph') 
    self.datat =[] 
    self.datay=[] 
    self.pitem.curve.setData(self.datat,self.datay) 

掃描被修改爲在數據在另一個線程中繪製時停止。 sync_to_plot停止線程執行,直到self._wait = False。該值由wait_state更改。

def scan (self): 
    thread_name = QThread.currentThread().objectName() 
    #thread_id = str(QThread.currentThreadId())#review 
    self.sig_msg.emit('Scanning '+thread_name) 
    for step in range(nsamples): 
     data = self.read_reg(reg[thread_name]) 
     self.sig_data.emit(step, data) 
     #pause while plot values 
     self.sync_to_plot() 
     if step % refrate == 0: 
      log.debug("%5d : %d" % (step, data)) 
     if self.__abort: 
      self.sig_msg.emit('scan stoped by user') 
      break 
    self.sig_done.emit(thread_name) 

def sync_to_plot(self): 
    self._wait=True 
    while self._wait: 
     log.debug("waiting") 
     QThread.currentThread().msleep(1) 
     app.processEvents() 
def wait_state(self, stat): 
    self._wait=stat 

這樣做的最後一個變化是在on_scaner_data上解鎖正在等待sync_to_plot的線程。

@pyqtSlot(int, int) 
def on_scaner_data(self, t: int, y: int): 
    app.processEvents() 
    self.debugBox.insertPlainText('t: '+str(t)+'y: '+str(y)+'\n') 
    self.debugBox.ensureCursorVisible() 
    self.MainGraph.update_fig(t,y) 
    for thread, scaner in self.__threads: 
     scaner.wait_state(False) 
     log.debug("scanner false")