How to close serial port when closing window with pyqt5

1.2k Views Asked by At

This code reads the output of the arduino fine and live plots the values. But when I close the window, the serial connection doesn't close.

import pyqtgraph as pg
from PyQt5 import QtCore, QtWidgets, QtSerialPort
import sys

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        self.graphWidget = pg.PlotWidget()
        self.setCentralWidget(self.graphWidget)

        self.x = list(range(100))  
        self.y = [0 for _ in range(100)] 

        self.graphWidget.setBackground('w')

        pen = pg.mkPen(color=(255, 0, 0))
        self.data_line =  self.graphWidget.plot(self.x, self.y, pen=pen)

        self.serial_port = QtSerialPort.QSerialPort("COM3")
        self.serial_port.setBaudRate(QtSerialPort.QSerialPort.Baud9600)
        self.serial_port.errorOccurred.connect(self.handle_error)
        self.serial_port.readyRead.connect(self.handle_ready_read)
        self.serial_port.open(QtCore.QIODevice.ReadWrite)

    def handle_ready_read(self):
        while self.serial_port.canReadLine():
            codec = QtCore.QTextCodec.codecForName("UTF-8")
            line = codec.toUnicode(self.serial_port.readLine()).strip().strip('\x00')
            try:
                print(line)
                value = float(line)
            except ValueError as e:
                print("error", e)
            else:
                self.update_plot(value)


    def handle_error(self, error):
        if error == QtSerialPort.QSerialPort.NoError:
            return
        print(error, self.serial_port.errorString())

    def update_plot(self, value):
        self.y = self.y[1:] + [value]
        self.x = self.x[1:]  
        self.x.append(self.x[-1] + 1)  
        self.data_line.setData(self.x, self.y) 

app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()

app.exec_()
    

How do I make sure the serial port closes when the window is closed? Maybe a button to close it on the window would be a better idea.

If I put serial_port = QtSerialPort.QSerialPort("COM3") outside the main window (then put self.serial_port = serial_port inside the main window init), then I can put serial_port.close() at the end of the file. But I don't know if this could cause problems trying some things if the serial port connection wasn't initialized in the main window.

1

There are 1 best solutions below

0
eyllanesc On BEST ANSWER

If you want to terminate the connection when the window closes then do it in the closeEvent method:

class MainWindow(QtWidgets.QMainWindow):
    # ...
    def closeEvent(self, event):
        super(MainWindow, self).closeEvent(event)
        self.serial_port.close()