More generally, you should not directly interact with any part of the GUI
from outside the main thread.
I remember being surprised by this when I first started working with Qt,
but found that it was true of every other GUI toolkit as well.

On Thu, Nov 16, 2017 at 6:46 PM, Patrick <[email protected]> wrote:

> So it looks like updating the plot data from an outside thread is just a
> Bad Idea. Here is the same example wrapping the callback in a Qt
> Signal/Slot pattern. Note that signals need to be defined inside a QObject,
> hence the explicit instantiation of a GraphicsLayoutWidget. So far it seems
> to work as expected.
>
> import numpy as np
> from PyQt5 import QtWidgets
> from PyQt5.QtCore import pyqtSignal, pyqtSlot
> import pyqtgraph as pg
> from pyqtgraph.Qt import QtCore, QtGui
> from pyqtgraph import GraphicsLayoutWidget
> from threading import Thread, Event
> import time
>
> # Routine to acquire and serve data
> # This might be a camera driver, notifying when a new frame is available
> def generate_data(callback, threadkill):
>     while not threadkill.is_set():
>         width = 1600
>         data = np.zeros(width)
>         data += np.cos(np.arange(0, 10*np.pi, 10*np.pi/width) -
> 9*time.monotonic())
>         data += np.cos(np.arange(0, 4*np.pi, 4*np.pi/width) +
> 4*time.monotonic())
>         callback(data)
>         time.sleep(0.01)
>
> class PyQtGraphTest(GraphicsLayoutWidget):
>
>     # Signal to indicate new data acquisition
>     # Note: signals need to be defined inside a QObject class/subclass
>     data_acquired = pyqtSignal(np.ndarray)
>
>     def __init__(self):
>
>         super().__init__()
>
>         self.setWindowTitle('Test pyqtgraph paint signals')
>         self.resize(640, 400)
>         self.plot = self.addPlot()
>         self.spectrum = self.plot.plot()
>         self.plot.enableAutoRange(pg.ViewBox.XYAxes)
>
>         # Connect the signal
>         self.data_acquired.connect(self.update_data)
>
>         # Make and start the background thread to acquire data
>         # Pass it the signal.emit as the callback function
>         self.threadkill = Event()
>         self.thread = Thread(target=generate_data,
> args=(self.data_acquired.emit, self.threadkill))
>         self.thread.start()
>
>     # Kill our data acquisition thread when shutting down
>     def closeEvent(self, close_event):
>         self.threadkill.set()
>
>     # Slot to receive acquired data and update plot
>     @pyqtSlot(np.ndarray)
>     def update_data(self, data):
>         self.spectrum.setData(data)
>
> if __name__ == '__main__':
>     import sys
>     app = QtWidgets.QApplication(sys.argv)
>     window = PyQtGraphTest()
>     window.show()
>     if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
>         sys.exit(app.exec_())
>
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "pyqtgraph" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To view this discussion on the web visit https://groups.google.com/d/
> msgid/pyqtgraph/33354545-4130-46cb-a9c6-91720c819780%40googlegroups.com
> <https://groups.google.com/d/msgid/pyqtgraph/33354545-4130-46cb-a9c6-91720c819780%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"pyqtgraph" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/pyqtgraph/CACZXET_ionT6kVNPc_s-A4QKDm2p24%3DYdRUxKHVPA2J%3D9CRvqQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to