scypy.signal.decimate()冻结了GUI

时间:2016-03-21 14:07:00

标签: python qt user-interface qthread resampling

我必须用大量样本(最多4e6个样本)绘制信号。我使用的是python 2.7,Qt 4.8和pyqtgraph 0.9.10。

我做了类似的事情:

  1. 生成信号并对其进行抽取(在单独的QThread中)
  2. 绘制信号并调用setDownsample()和clipToView()(pyqtgraph的方法)
  3. 问题是当QThread for decimate计算时,GUI会冻结。这是我的代码:

    class TestDecimate(QDialog):
    
        def __init__(self, parent=None):
            super(TestDecimate, self).__init__(parent)
    
            self.decimate_thread = GenerateBigPlotThread()
    
            layout = QGridLayout()
    
            graph_widget = pg.GraphicsLayoutWidget()
            graph_layout = graph_widget.addLayout()
    
            self.p = graph_layout.addPlot(title="Plot 2", col=1, row=2)
            self.curve1 = self.p.plot([], pen=(255, 0, 0))
            self.curve2 = self.p.plot([], pen=(255, 255, 0))
            self.curve3 = self.p.plot([], pen=(255, 0, 255))
            self.curve4 = self.p.plot([], pen=(0, 0, 255))
            self.p.showGrid(True, True, 0.3)
    
            self.legend = pg.LegendItem(offset=(-10,10))
            self.legend.addItem(self.curve1, name="Test")
            self.legend.addItem(self.curve2, name="Test1")
            self.legend.addItem(self.curve3, name="Test2")
            self.legend.addItem(self.curve4, name="Test3")
            self.legend.setParentItem(self.p.getViewBox())
    
            self.start_pb = QPushButton("Generate")
    
            layout.addWidget(graph_widget, 1, 1)
            layout.addWidget(self.start_pb, 2, 1)
    
            self.setLayout(layout)
    
            self.start_pb.clicked.connect(self.start_thread_for_decimate)
            self.decimate_thread.newData.connect(self.set_data)
    
        def set_data(self, y, z, n, m):
            print "Plotting"
            self.curve1.setData(y)
            self.curve2.setData(z)
            self.curve3.setData(n)
            self.curve4.setData(m)
    
            self.p.setDownsampling(ds=True, auto=True, mode='peak')
            self.p.setClipToView(clip=True)
            self.p.getViewBox().enableAutoRange(axis=ViewBox.XYAxes)
            print "Plotting done"
    
    
        def start_thread_for_decimate(self):
            self.decimate_thread.start()
    
    if __name__ == "__main__":
         app = QApplication(sys.argv)
         main = TestDecimate()
         main.show()
         sys.exit(app.exec_())
    

    用于计算和抽取的线程:

    class GenerateBigPlotThread(QThread):
    
        newData = QtCore.pyqtSignal("PyQt_PyObject","PyQt_PyObject","PyQt_PyObject","PyQt_PyObject")
    
        def __init__(self,*arg,**kwargs):
            super(GenerateBigPlotThread, self).__init__(*arg,**kwargs)
    
        def run(self):
    
            self.num_points = 4e6
    
            x = np.arange(self.num_points)
            y = np.sin(3.14159 * x * 10/self.num_points)
            z = np.cos(3.14159 * x * 10/self.num_points)
            n = np.sin(3.14159 * x * 5/self.num_points)
            m = np.cos(3.14159 * x * 5/self.num_points)
            print "Decimate"
            y = decimate(y, 4, ftype='fir')
            z = decimate(z, 4, ftype='fir')
            n = decimate(n, 4, ftype='fir')
            m = decimate(m, 4, ftype='fir')
            print "Done!"
    
            self.newData.emit(y, z, n, m)
    

    启动线程时,查看问题的最佳方法是移动图例。 此外,我尝试scipy.signal.resample(4e6样本到1e6样本)而不是抽取,并发生同样的问题。 有人能告诉我这种行为的原因是什么?

1 个答案:

答案 0 :(得分:0)

问题在于scipy的版本。我有scipy 0.13.2,在我升级到0.17.0之后,问题似乎已经解决了。不过,我想知道为什么这样的事情一开始就有可能。