Running multiple plots with pyside2
-
I am trying to run multiple plot window in threads.
from PySide2.QtWidgets import QApplication import sys from pyqtgraph import GraphicsLayoutWidget from pyqtgraph.Qt import QtCore import numpy as np import pyqtgraph as pg import threading class AnotherWindow(GraphicsLayoutWidget): def __init__(self): super().__init__() pg.setConfigOptions(antialias=True) self.p6 = self.addPlot(title="Updating plot") self.curve = self.p6.plot(pen='y') self.data = np.random.normal(size=(10, 1000)) self.ptr = 0 self.timer = QtCore.QTimer() self.timer.timeout.connect(self.update) self.timer.start(50) def update(self): self.curve.setData(self.data[self.ptr % 10]) if self.ptr == 0: self.p6.enableAutoRange('xy', False) self.ptr += 1 app = QApplication(sys.argv) def th(): w = AnotherWindow() w.show() mythread = threading.Thread(target=th) mythread.start() mythread.join()
It gives following error:
QObject: Cannot create children for a parent that is in a different thread. (Parent is QApplication(0x323e610), parent's thread is QThread(0x3179fd0), current thread is QThread(0x7f6834001640) QObject::startTimer: Timers can only be used with threads started with QThread QObject::startTimer: Timers can only be used with threads started with QThread QBasicTimer::start: QBasicTimer can only be used with threads started with QThread QBasicTimer::start: QBasicTimer can only be used with threads started with QThread ...
It works when I run it directly.
app = QApplication(sys.argv) w = AnotherWindow() w.show() app.exec_()
but I want to do something like this:
mythread = threading.Thread(target=th) mythread.start() mythread1 = threading.Thread(target=th) mythread1.start()
-
@anoop1 Your AnotherWindow instance is created in main thread. You should at least change your code, so that this instance is created in the new thread.
But I doubt this approach will work at all as Qt GUI classes can only be used in main thread (GUI thread). -
@jsulm thanks for reply.
I have tried
app = QApplication(sys.argv) w = AnotherWindow() def th(): w.show() mythread = threading.Thread(target=th) mythread.start()
but now plot is not updating.
there is another approach that I am trying:
from PySide2.QtWidgets import QApplication, QMainWindow import sys from pyqtgraph import GraphicsLayoutWidget from pyqtgraph.Qt import QtCore import numpy as np import pyqtgraph as pg class AnotherWindow(GraphicsLayoutWidget): def __init__(self): super().__init__() pg.setConfigOptions(antialias=True) self.p6 = self.addPlot(title="Updating plot") self.curve = self.p6.plot(pen='y') self.data = np.random.normal(size=(10, 1000)) self.ptr = 0 self.timer = QtCore.QTimer() self.timer.timeout.connect(self.update) self.timer.start(50) def update(self): self.curve.setData(self.data[self.ptr % 10]) if self.ptr == 0: self.p6.enableAutoRange('xy', False) self.ptr += 1 class MainWindow(QMainWindow): def __init__(self): super().__init__() self.w = [] self.show_new_window() self.show_new_window() def show_new_window(self): self.w.append(AnotherWindow()) self.w[-1].show() app = QApplication(sys.argv) w = MainWindow() app.exec_()
It shows 2 plot window.
but when I move this code in my cmd module it get stuck
class CLI(cmd.Cmd): def __init__(self): super().__init__() self.app = QApplication(sys.argv) self.w = MainWindow() if __name__ == '__main__': CLI().cmdloop()
-
@JonB means it opens 2 window with black screen, (looks like GUI thread gets stuck).
this is complete code:
from PySide2.QtWidgets import QApplication, QMainWindow import sys from pyqtgraph import GraphicsLayoutWidget from pyqtgraph.Qt import QtCore import numpy as np import pyqtgraph as pg import cmd class AnotherWindow(GraphicsLayoutWidget): def __init__(self): super().__init__() pg.setConfigOptions(antialias=True) self.p6 = self.addPlot(title="Updating plot") self.curve = self.p6.plot(pen='y') self.data = np.random.normal(size=(10, 1000)) self.ptr = 0 self.timer = QtCore.QTimer() self.timer.timeout.connect(self.update) self.timer.start(50) def update(self): self.curve.setData(self.data[self.ptr % 10]) if self.ptr == 0: self.p6.enableAutoRange('xy', False) self.ptr += 1 class MainWindow(QMainWindow): def __init__(self): super().__init__() self.w = [] self.show_new_window() self.show_new_window() def show_new_window(self): self.w.append(AnotherWindow()) self.w[-1].show() class CLI(cmd.Cmd): def __init__(self): super().__init__() self.app = QApplication(sys.argv) self.w = MainWindow() if __name__ == '__main__': CLI().cmdloop()
-
this is complete code:
-
Why would you have a
MainWindow
but never show it? -
After
CLI().cmdloop()
has been executed,CLI
and everything else goes out of scope. Your program then exits since it never executes the Qt event loop.
Since you are choosing to use Python
Cmd.cmdloop
I suggest you investigate that as a Python question. Goodness knows how it interacts with Qt. -
-
@JonB My aim to show plot when user uses plot command so there can be multiple plot window on the screen at a given time, above code I got from https://www.learnpyqt.com/tutorials/creating-multiple-windows/ and trying to adjust it so it will work with CMD module but it is not working.