2

As the title says, my plot does not update. The objetive is to initiate the plot when the button is clicked. The window pops up and the axis are formed, but no curve is plotted. i used pyqt5 in qt designer fr the GUI and pyqtgraph for the plot. if i wanted to add more plots in the same window whats the optimal way to do it. Thanks

Code:

from PyQt5 import QtCore, QtGui, QtWidgets
import os,serial,jeje_rc
os.environ["TF_CPP_MIN_LOG_LEVEL"]="3"
import numpy as np
import pyqtgraph as pg




class Ui_MainWindow(object):

def ser(self):
    self.raw = serial.Serial('COM4', 9600)
    self.raw.close()
    self.raw.open()

def update(self):
    self.datos = self.raw.readline()
    self.datos1 = self.datos.decode().split(',')
    self.y1[self.m] = self.datos1[0]

    if self.m == 99:
        self.y1 = np.zeros(100, dtype=float)
        self.m = 0
    else:
        self.m += 1

    self.curva1.setData(self.y1)
    app.processEvents()

def start(self):
    self.ser()
    self.win = pg.GraphicsWindow()
    self.win.setWindowTitle('Datos de arduino')
    self.p1 = self.win.addPlot()
    self.p1.setYRange(0, 1024, padding=0)
    self.curva1 = self.p1.plot()
    self.datos = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
    self.y1 = np.zeros(100, dtype=float)


def setupUi(self, MainWindow):
    MainWindow.setObjectName("MainWindow")
    MainWindow.setWindowTitle("ECG de 12 Derivaciones UAO")
    MainWindow.resize(800, 550)
    self.m=0      
    self.centralwidget = QtWidgets.QWidget(MainWindow)
    self.centralwidget.setMaximumSize(QtCore.QSize(805, 510))
    self.centralwidget.setObjectName("centralwidget")
    self.centralwidget.setWindowTitle("ECG de 12 Derivaciones UAO")
    self.label = QtWidgets.QLabel(self.centralwidget)
    self.label.setGeometry(QtCore.QRect(20, 270, 241, 19))
    self.label.setObjectName("label")
    self.line = QtWidgets.QFrame(self.centralwidget)
    self.line.setGeometry(QtCore.QRect(10, 230, 781, 20))
    self.line.setFrameShape(QtWidgets.QFrame.HLine)
    self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
    self.line.setObjectName("line")
    self.label_2 = QtWidgets.QLabel(self.centralwidget)
    self.label_2.setGeometry(QtCore.QRect(600, 40, 181, 171))
    self.label_2.setObjectName("label_2")
    self.label_3 = QtWidgets.QLabel(self.centralwidget)
    self.label_3.setGeometry(QtCore.QRect(40, 10, 591, 41))
    font = QtGui.QFont()
    font.setPointSize(16)
    self.label_3.setFont(font)
    self.label_3.setObjectName("label_3")
    self.label_4 = QtWidgets.QLabel(self.centralwidget)
    self.label_4.setGeometry(QtCore.QRect(170, 150, 221, 41))
    font = QtGui.QFont()
    font.setPointSize(11)
    self.label_4.setFont(font)
    self.label_4.setObjectName("label_4")
    self.label_5 = QtWidgets.QLabel(self.centralwidget)
    self.label_5.setGeometry(QtCore.QRect(110, 190, 471, 41))
    font = QtGui.QFont()
    font.setPointSize(11)
    self.label_5.setFont(font)
    self.label_5.setObjectName("label_5")
    self.label_6 = QtWidgets.QLabel(self.centralwidget)
    self.label_6.setGeometry(QtCore.QRect(50, 100, 521, 51))
    font = QtGui.QFont()
    font.setPointSize(9)
    self.label_6.setFont(font)
    self.label_6.setObjectName("label_6")
    self.lineEdad = QtWidgets.QLineEdit(self.centralwidget)
    self.lineEdad.setGeometry(QtCore.QRect(110, 310, 261, 21))
    self.lineEdad.setObjectName("lineEdad")
    self.lineNombre = QtWidgets.QLineEdit(self.centralwidget)
    self.lineNombre.setGeometry(QtCore.QRect(110, 270, 261, 20))
    self.lineNombre.setObjectName("lineNombre")
    self.BotonInicio = QtWidgets.QPushButton(self.centralwidget)
    self.BotonInicio.setGeometry(QtCore.QRect(490, 290, 181, 41))
    self.BotonInicio.setObjectName("BotonInicio")
    self.BotonInicio.clicked.connect(self.start)
    self.label_7 = QtWidgets.QLabel(self.centralwidget)
    self.label_7.setGeometry(QtCore.QRect(20, 310, 68, 19))
    self.label_7.setObjectName("label_7")
    self.label_8 = QtWidgets.QLabel(self.centralwidget)
    self.label_8.setGeometry(QtCore.QRect(20, 350, 61, 19))
    self.label_8.setObjectName("label_8")
    self.label_9 = QtWidgets.QLabel(self.centralwidget)
    self.label_9.setGeometry(QtCore.QRect(20, 380, 111, 31))
    self.label_9.setObjectName("label_9")
    self.BoxGenero = QtWidgets.QComboBox(self.centralwidget)
    self.BoxGenero.setGeometry(QtCore.QRect(110, 350, 92, 25))
    self.BoxGenero.setObjectName("BoxGenero")
    self.BoxGenero.addItem("")
    self.BoxGenero.addItem("")
    self.plainTextPatologias = QtWidgets.QPlainTextEdit(self.centralwidget)
    self.plainTextPatologias.setGeometry(QtCore.QRect(110, 390, 261, 91))
    self.plainTextPatologias.setObjectName("plainTextPatologias")
    self.line_2 = QtWidgets.QFrame(self.centralwidget)
    self.line_2.setGeometry(QtCore.QRect(390, 250, 20, 241))
    self.line_2.setFrameShape(QtWidgets.QFrame.VLine)
    self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
    self.line_2.setObjectName("line_2")
    self.BotonExportar = QtWidgets.QPushButton(self.centralwidget)
    self.BotonExportar.setGeometry(QtCore.QRect(490, 410, 181, 41))
    self.BotonExportar.setObjectName("BotonExportar")
    MainWindow.setCentralWidget(self.centralwidget)
    self.menubar = QtWidgets.QMenuBar(MainWindow)
    self.menubar.setGeometry(QtCore.QRect(0, 0, 805, 31))
    self.menubar.setObjectName("menubar")
    MainWindow.setMenuBar(self.menubar)
    self.statusbar = QtWidgets.QStatusBar(MainWindow)
    self.statusbar.setObjectName("statusbar")
    MainWindow.setStatusBar(self.statusbar)


    self.retranslateUi(MainWindow)
    QtCore.QMetaObject.connectSlotsByName(MainWindow)
    timer = QtCore.QTimer()
    timer.timeout.connect(self.update)
    timer.start(0)


def retranslateUi(self, MainWindow):
    _translate = QtCore.QCoreApplication.translate
    MainWindow.setWindowTitle(_translate("MainWindow", "ECG de 12 Derivaciones"))
    self.label.setText(_translate("MainWindow", "Nombre:"))
    self.label_2.setText(_translate("MainWindow", "<html><head/><body><p><img src=\":/newPrefix/logo-universidad-autonoma-de-occidente.png\"/></p></body></html>"))
    self.label_3.setText(_translate("MainWindow", "Electrocardiógrafo De 12 Derivaciones"))
    self.label_4.setText(_translate("MainWindow", "Facultad de ingenieria"))
    self.label_5.setText(_translate("MainWindow", " Universidad Autonoma De Occidente"))
    self.label_6.setText(_translate("MainWindow", "Por: Mario Gomez, Viviana Calero, Sara Chillito, Stefania Calderon"))
    self.BotonInicio.setText(_translate("MainWindow", "Inicio del programa"))
    self.label_7.setText(_translate("MainWindow", "Edad:"))
    self.label_8.setText(_translate("MainWindow", "Genero:"))
    self.label_9.setText(_translate("MainWindow", "Patologias:"))
    self.BoxGenero.setItemText(0, _translate("MainWindow", "Hombre"))
    self.BoxGenero.setItemText(1, _translate("MainWindow", "Mujer"))
    self.BotonExportar.setText(_translate("MainWindow", "Exportar datos"))



if __name__ == "__main__":
  import sys
  app = QtWidgets.QApplication(sys.argv)
  MainWindow = QtWidgets.QMainWindow()
  ui = Ui_MainWindow()
  ui.setupUi(MainWindow)
  MainWindow.show()
  sys.exit(app.exec_())

1 Answers1

2

It is recommended not to modify the code provided by Qt Designer since if you want to modify the design you will have to rewrite your code, besides the Ui_MainWindow class is not a widget but a class that is used to fill some widget, so I recommend deleting the changes .

On the other hand is not suitable to run with a timer with a range of 0, since it does not allow updating the GUI, on the other hand the reading of the serial is blocking, so a possible solution is to use QThread, and use a signal to update the data in the GUI thread.

class Ui_MainWindow(object):
    ...

class ArduinoThread(QtCore.QThread):
    dataChanged = QtCore.pyqtSignal(str)
    def __init__(self, *args, **kwargs):
        QtCore.QThread.__init__(self, *args, **kwargs)
        self.raw = serial.Serial('com4', 9600)
        self.raw.close()
        self.raw.open()

    def run(self):
        while True:
            datos_array = self.raw.readline().decode().split(',')
            if datos_array:
                datos = datos_array[0]
            self.dataChanged.emit(datos)
            QtCore.QThread.msleep(10)

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, *args, **kwargs):
        QtWidgets.QMainWindow.__init__(self, *args, **kwargs)
        self.setupUi(self)
        self.BotonInicio.clicked.connect(self.start)
        self.m = 0

    def update_plot(self, dato):
        if self.m > 99:
            self.y1 = np.zeros(100, dtype=float)
            self.m = 0
        else:
            self.y1[self.m] = dato
            self.m += 1
        self.curva1.setData(self.y1)

    def start(self):
        thread = ArduinoThread(self)
        thread.dataChanged.connect(self.update_plot)
        thread.start()
        self.win = pg.GraphicsWindow()
        self.win.setWindowTitle('Datos de arduino')
        self.p1 = self.win.addPlot()
        self.p1.setYRange(0, 1024, padding=0)
        self.curva1 = self.p1.plot()
        self.y1 = np.zeros(100, dtype=float)


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

As you can see, I have made some changes to improve the application as verifications, use variables when necessary, etc.


Although a way compatible with Qt is to use QSerialPort that emits the readyRead signal when there is a new data:

from PyQt5 import QtCore, QtGui, QtWidgets, QtSerialPort
....

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, *args, **kwargs):
        QtWidgets.QMainWindow.__init__(self, *args, **kwargs)
        self.setupUi(self)
        self.BotonInicio.clicked.connect(self.start)

    def update_plot(self):
        while self.ser.canReadLine():
            line = bytearray(self.ser.readLine()).decode()
            self.processLine(line)

    def processLine(self, line):
        datos_array = line.strip().split(',')
        if datos_array:
            dato = datos_array[0]
            if self.m > 99:
                self.y1 = np.zeros(100, dtype=float)
                self.m = 0
            else:
                self.y1[self.m] = dato
                self.m += 1

            self.curva1.setData(self.y1)

    def start(self):
        self.ser = QtSerialPort.QSerialPort("com4", self)
        self.ser.setBaudRate(9600)
        self.ser.readyRead.connect(self.update_plot)
        self.ser.open(QtSerialPort.QSerialPort.ReadOnly)
        self.win = pg.GraphicsWindow()
        self.win.setWindowTitle('Datos de arduino')
        self.p1 = self.win.addPlot()
        self.p1.setYRange(0, 1024, padding=0)
        self.curva1 = self.p1.plot()
        self.y1 = np.zeros(100, dtype=float)


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241