繁体   English   中英

Chaco和PyQt无法发出信号

[英]Signal fails to emit with Chaco and PyQt

我正在尝试与Chaco和pyqt合作,为实验室硬件绘制实时数据采集任务。 我以前使用过matplotlib,但是事实证明它太慢了(我什至尝试了动画)。 当我在pyqt窗口中嵌入matplotlib图时,以下代码可以正常工作,但是使用chaco,当我从线程内部发出更新信号时,没有任何反应。 如果您不使用线程进行模拟采集,则此代码将起作用。 我尝试使用qthreads也无济于事(包括类似以下内容: PyQt中的线程和信号问题 )。 有没有人使用pyqt + chaco +线程来帮助我找到我要去的地方,或者发生了什么?

import sys
import threading, time
import numpy as np

from enthought.etsconfig.etsconfig import ETSConfig
ETSConfig.toolkit = "qt4"

from enthought.enable.api import Window
from enthought.chaco.api import ArrayPlotData, Plot

from PyQt4 import QtGui, QtCore


class Signals(QtCore.QObject):
    done_collecting = QtCore.pyqtSignal(np.ndarray, np.ndarray)

class PlotWindow(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)

        x = np.linspace(0,2*np.pi,200)
        y = np.sin(x)
        plotdata = ArrayPlotData(x=x, y=y)
        plot = Plot(plotdata, padding=50, border_visible=True)
        plot.plot(('x', 'y'))

        window = Window(self,-1, component=plot)
        self.setCentralWidget(window.control)
        self.resize(500,500)

        self.pd = plotdata

    def update_display(self, x, y):
        print 'updating'
        self.pd.set_data('x', x)
        self.pd.set_data('y', y)


def run_collection(signal):
    # this is where I would start and stop my hardware,
    # but I will just call the read function myself here
    for i in range(1,10):
        every_n_collected(i, signal)
        time.sleep(0.5)

def every_n_collected(frequency, signal):
    # dummy data to take place of device read
    x = np.linspace(0,2*np.pi,200)
    y = np.sin(x*frequency)
    print 'emitting'
    signal.emit(x, y)
    QtGui.QApplication.processEvents()

def main():
    plt = PlotWindow()
    plt.show()
    QtGui.QApplication.processEvents()

    signals = Signals()
    signals.done_collecting.connect(plt.update_display)

    t = threading.Thread(target=run_collection, args=(signals.done_collecting,))
    t.start()
    t.join()
    QtGui.QApplication.processEvents()    

    # it works without threads though...
    # run_collection(signals.done_collecting)

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    main()

您对主线程(UI线程)上的join的调用阻止了该线程,并阻止了UI处理事件。 如果您在主函数中启动了app / GUI事件循环,并在不调用t.join()的情况下等待应用程序关闭,则它应该可以正常工作。

这是使用常规Traits / TraitsUI / Chaco应用程序进行操作的方法。

import time
import threading

import numpy as np

from traits.etsconfig.etsconfig import ETSConfig
ETSConfig.toolkit = "qt4"

from enable.api import ComponentEditor
from chaco.api import ArrayPlotData, Plot

from traits.api import Event, HasTraits, Instance
from traitsui.api import View, Item

class PlotWindow(HasTraits):

    dataset = Instance(ArrayPlotData)
    plot = Instance(Plot)

    def _dataset_default(self):
        x = np.linspace(0,2*np.pi,200)
        y = np.sin(x)
        plotdata = ArrayPlotData(x=x, y=y)
        return plotdata

    def _plot_default(self):
        plot = Plot(self.dataset, padding=50, border_visible=True)
        plot.plot(('x', 'y'))
        return plot

    def update_display(self, x, y):
        print 'updating', threading.current_thread()
        self.dataset.set_data('x', x)
        self.dataset.set_data('y', y)

    traits_view = View(
        Item('plot', editor=ComponentEditor(size=(400, 400)), show_label=False)
    )

def run_collection(datamodel):
    # this is where I would start and stop my hardware,
    # but I will just call the read function myself here
    for i in range(1,10):
        x = np.linspace(0,2*np.pi,200)
        y = np.sin(x*i)
        datamodel.update_display(x, y)
        time.sleep(0.5)

def main():
    plot = PlotWindow()

    t = threading.Thread(target=run_collection, args=(plot,))
    t.start()

    # Starts the UI and the GUI mainloop
    plot.configure_traits()

    # don't call t.join() as it blocks the current thread...

if __name__ == "__main__":
    main()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM