I want to perform event processing in pyqtgraph

Asked 2 years ago, Updated 2 years ago, 88 views

I don't know how to run the program below and finish it properly when I close win1,win2 in the window I created.
I'd like to write a code like the so-called event handler in pyqtgraph, so please tell me what it will be like.

from numpy import*
from pyqtgraph.Qtimport QtGui, QtCore
import pyqtgraph aspg
import serial

# Create object serial port
portName = "COM6"                     
baudrate= 115200
ser=serial.Serial(portName,baudrate)

### START QtApp#####
app=QtGui.QApplication([])#you MUST do this once(initialize things)
####################

win1=pg.GraphicsWindow(title="Signal from serial port")#creates a window
win2=pg.GraphicsWindow(title="signal calculation")
p1=win1.addPlot(title="Realtime plot")#creates empty space for the plot in the window
p2=win2.addPlot(title="inference")
curve1 = p1.plot()# create an empty "plot" (a curve to plot)
curve2 = p2.plot()

windowWidth=500#width of the window displaying the curve
Create 500 #0s (Xm)
Xm=linspace(0,0, windowWidth)#create array that will contain the release time series 
Ym = linspace(0,0, windowWidth)
Zm = linspace(0,0, windowWidth)
ptr=-windowWidth# set first x position

# Realtime data slot.Each time this function is called, the data display is updated
default():
    global curve, ptr, Xm, Ym
        
    Xm[:-1] = Xm[1:] #shift data in the temporary mean 1 sample left
    Ym[:-1] = Ym[1:]
    Zm[:-1] = Zm[1:]
    bolt=ser.readline().rstrip()#Replace the information (string) received in the serial communication until a new line code arrives.obtain by byte type
    volt=volt.decode()
    bolt=float(volt)
    Xm[-1]=volt#vector containing the instantaneous values  
    Ym[-1] = bolt
    ptr+=1# update x position for displaying the curve
    curve1.setData(Xm)#set the curve with this data
    curve1.setPos(ptr,0)#set x position in the graph to 0
    x = Ym [len(Ym)-131:len(Ym)-1] # Convert with appropriate function
    k = cal(x)
    Zm[-1] = k
    curve2.setData(Zm)
    curve2.setPos(ptr,0)
    QtGui.QApplication.processEvents()#you MUST process the plot now

### MAIN PROGRAM #####    
# This is a vital infinite loop calling your realtime data slot
while True—update()

### END QtApp####
pg.QtGui.QApplication.exec_()#you MUST put this at the end
##################

python windows jupyter-notebook pyqt

2022-09-30 15:04

1 Answers

The way of displaying windows and updating data is just not in line with the normal way, so if you close either window by clicking on the close box (top right x), you don't have to be particularly aware of the event unless you want to close both at the same time.

Also, regarding the GraphicsWindow() method used, the latest specification says DEPRECATED, so you should review it.
Deprecated Window Classes

The source of the question will be two questions:

This article will help you with the corrections.
How to install Python/pyqtgraph and launch a sample
Using Python pyqtgraph

The following are the three points to be corrected.(Third one doesn't matter)

This will exit the program and return to the command prompt when you close both of the displayed windows.(I use Python instead of JupiterNotebook)

The following comment in ##■ is the change.

from numpy import*
from pyqtgraph.Qtimport QtGui, QtCore
import pyqtgraph aspg
import serial
import random

# Create object serial port
portName = "COM6"                     
baudrate= 115200
ser=serial.Serial(portName,baudrate)

### START QtApp#####
app=QtGui.QApplication([])#you MUST do this once(initialize things)
####################

win1=pg.GraphicsWindow(title="Signal from serial port")#creates a window
win2=pg.GraphicsWindow(title="signal calculation")
p1=win1.addPlot(title="Realtime plot")#creates empty space for the plot in the window
p2=win2.addPlot(title="inference")
curve1 = p1.plot()# create an empty "plot" (a curve to plot)
curve2 = p2.plot()

windowWidth=500#width of the window displaying the curve
Create 500 #0s (Xm)
Xm=linspace(0,0, windowWidth)#create array that will contain the release time series 
Ym = linspace(0,0, windowWidth)
Zm = linspace(0,0, windowWidth)
ptr=-windowWidth# set first x position

# Realtime data slot.Each time this function is called, the data display is updated
default():
    global curve, ptr, Xm, Ym
        
    Xm[:-1] = Xm[1:] #shift data in the temporary mean 1 sample left
    Ym[:-1] = Ym[1:]
    Zm[:-1] = Zm[1:]
    bolt=ser.readline().rstrip()#Replace the information (string) received in the serial communication until a new line code arrives.obtain by byte type
    volt=volt.decode()
    bolt=float(volt)
    Xm[-1]=volt#vector containing the instantaneous values  
    Ym[-1] = bolt
    ptr+=1# update x position for displaying the curve
    curve1.setData(Xm)#set the curve with this data
    curve1.setPos(ptr,0)#set x position in the graph to 0
    x = Ym [len(Ym)-131:len(Ym)-1] # Convert with appropriate function
    k = cal(x)
    Zm[-1] = k
    curve2.setData(Zm)
    curve2.setPos(ptr,0)
    ##■ Comment out QtGui.QApplication.processEvents()#you MUST process the plot now

### MAIN PROGRAM #####    
# This is a vital infinite loop calling your realtime data slot
##■ while True: update()####Remove infinite loop

### END QtApp####
##■ pg.QtGui.QApplication.exec_()#you MUST put this at the end### Move below
##################

##■ PyQt Normal Calling Method
if__name__=='__main__':
    import sys
    
    ##■ Configuring Interval Timers for Serial Port Read and Graph Update Processing
    timer=QtCore.QTimer()
    timer.timeout.connect(update)
    timer.start(30)## ■ Adjust the interval to match the serial port read interval
    
    ##■ Performing a PyQt Event Loop
    if(sys.flags.interactive!=1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

There was an article that looked just right, so I tried to merge it and use a new API, and put two graphs in one window, so I didn't have to worry about the closing event.
Pyqt5 with pyqtgraph building two graphs

The previous program also did so in confirmation, but the serial port input is simulated with random numbers.
Therefore, we have not verified that the input from the serial port is really working.

import sys
from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QApplication)
from pyqtgraph.Qtimport QtGui, QtCore
import pyqtgraph aspg
import numpy as np
import serial
import random

classCustomPlot(pg.PlotWidget):
    def__init__(self, title='):
        pg.PlotWidget.__init__(self, title=title)
        self.curve=self.plot()

# The top container/widget for the graphs
class Window (QWidget):
    def__init__(self):
        super().__init__()
        
        self.windowWidth=500#width of the window displaying the curve
        Create 500 #0s (Xm)
        self.Xm=np.linspace(0,0,self.windowWidth)#create array that will contain the release time series 
        self.Ym=np.linspace(0,0,self.windowWidth)
        self.Zm=np.linspace(0,0,self.windowWidth)
        self.ptr=-self.windowWidth# set first x position
        self.k = 5#### Initial value for signal calculation alternative simulation
        
        self.initUI()#call the UI setup
        '''
        self.portName="COM6"
        self.baudrate=115200
        self.ser=serial.Serial(self.portName, self.baudrate)
        '''
        self.timer=QtCore.QTimer()
        self.timer.timeout.connect(self.updateGraph)
        self.timer.start(30)
    
    # setup the UI
    defaultUI(self):
        
        self.layout=QVBoxLayout(self)#create thelayout
        self.pginput=CustomPlot(title="Signal from serial port-Realtime slot")# class abstract both the classes
        self.pginfer=CustomPlot(title="signal calculation-inference")#"""""
        self.layout.addWidget(self.pginput)
        self.layout.addWidget(self.pginfer)
        self.show()
    
    # update graph
    defaultGraph(self):
        
        self.Xm[:-1] = self.Xm[1:] #shift data in the temporary mean 1 sample left
        self.Ym [:-1] = self.Ym [1:]
        self.Zm[:-1] = self.Zm[1:]
        '''
        self.volt=ser.readline().rstrip()#Replace the information (string) received in the serial communication until a new line code arrives.obtain by byte type
        self.volt=self.volt.decode()
        self.volt=float(self.volt)
        '''
        self.volt=random.randrange(0.0,6.0)#####Alternate Simulation of Input Signal
        self.Xm[-1] = self.volt #vector containing the instantaneous values
        self.Ym[-1] = self.volt
        self.ptr+=1# update x position for displaying the curve
        self.pginput.curve.setData(self.Xm)#set the curve with this data
        self.pginput.curve.setPos(self.ptr,0)#set x position in the graph to 0
        
        self.x = self.Ym [len(self.Ym)-131:len(self.Ym)-1] # Convert with appropriate function
        # self.k = cal(x)
        self.k+=random.randint (-5,5)#####Alternative simulation of above signal calculations
        self.Zm[-1] = self.k
        self.pginfer.curve.setData(self.Zm)
        self.pginfer.curve.setPos(self.ptr, 0)

if__name__=='__main__':
    app=QApplication(sys.argv)
    window=Window()
    sys.exit(app.exec_())


2022-09-30 15:04

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.