使用pyqt5关闭窗口时如何关闭串口

问题描述

代码读取 arduino 的输出并实时绘制值。但是当我关闭窗口时,串行连接并没有关闭

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))
        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_()
    

当窗口关闭时,如何确保串口关闭?也许在窗口上使用按钮关闭它会更好。

如果我将 serial_port = QtSerialPort.QSerialPort("COM3") 放在主窗口之外(然后将 self.serial_port = serial_port 放在主窗口初始化中),那么我可以将 serial_port.close() 放在文件的末尾。但我不知道如果串行端口连接没有在主窗口中初始化,这是否会导致尝试某些事情的问题。

解决方法

如果要在窗口关闭时终止连接,请在 closeEvent 方法中执行:

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