J'essaie de travailler avec Chaco et pyqt pour tracer une tâche d'acquisition de données en temps réel pour du matériel de laboratoire. J'utilisais auparavant matplotlib, mais il s'est avéré trop lent (j'ai même essayé l'animation). Le code suivant fonctionne bien lorsque j'intègre un tracé matplotlib dans une fenêtre pyqt, mais avec chaco, rien ne se passe lorsque j'émets mon signal de mise à jour depuis l'intérieur d'un thread. Ce code fonctionnera si vous n'utilisez pas de thread pour l'acquisition simulée. J'ai essayé d'utiliser qthreads sans succès non plus (y compris quelque chose comme ceci : Problème de threading et de signaux dans PyQt ). Y a-t-il quelqu'un qui a utilisé pyqt + chaco + threading et qui pourrait m'aider à trouver où je me trompe, ou ce qui se passe ?
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()