class NetworkMJPGImage(QQuickPaintedItem): def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self._stream_buffer = QByteArray() self._stream_buffer_start_index = -1 self._network_manager = None # type: QNetworkAccessManager self._image_request = None # type: QNetworkRequest self._image_reply = None # type: QNetworkReply self._image = QImage() self._image_rect = QRect() self._source_url = QUrl() self._started = False self._mirror = False self.setAntialiasing(True) ## Ensure that close gets called when object is destroyed def __del__(self) -> None: self.stop() def paint(self, painter: "QPainter") -> None: if self._mirror: painter.drawImage(self.contentsBoundingRect(), self._image.mirrored()) return painter.drawImage(self.contentsBoundingRect(), self._image) def setSourceURL(self, source_url: "QUrl") -> None: self._source_url = source_url self.sourceURLChanged.emit() if self._started: self.start() def getSourceURL(self) -> "QUrl": return self._source_url sourceURLChanged = pyqtSignal() source = pyqtProperty(QUrl, fget=getSourceURL, fset=setSourceURL, notify=sourceURLChanged) def setMirror(self, mirror: bool) -> None: if mirror == self._mirror: return self._mirror = mirror self.mirrorChanged.emit() self.update() def getMirror(self) -> bool: return self._mirror mirrorChanged = pyqtSignal() mirror = pyqtProperty(bool, fget=getMirror, fset=setMirror, notify=mirrorChanged) imageSizeChanged = pyqtSignal() @pyqtProperty(int, notify=imageSizeChanged) def imageWidth(self) -> int: return self._image.width() @pyqtProperty(int, notify=imageSizeChanged) def imageHeight(self) -> int: return self._image.height() @pyqtSlot() def start(self) -> None: self.stop() # Ensure that previous requests (if any) are stopped. if not self._source_url: Logger.log("w", "Unable to start camera stream without target!") return self._started = True Logger.log("w", "MJPEG starting stream...") self._image_request = QNetworkRequest(self._source_url) if self._network_manager is None: self._network_manager = QNetworkAccessManager() self._image_reply = self._network_manager.get(self._image_request) self._image_reply.downloadProgress.connect( self._onStreamDownloadProgress) @pyqtSlot() def stop(self) -> None: Logger.log("w", "MJPEG stopping stream...") self._stream_buffer = QByteArray() self._stream_buffer_start_index = -1 if self._image_reply: try: try: self._image_reply.downloadProgress.disconnect( self._onStreamDownloadProgress) except Exception: pass if not self._image_reply.isFinished(): self._image_reply.close() except Exception as e: # RuntimeError pass # It can happen that the wrapped c++ object is already deleted. self._image_reply = None self._image_request = None self._network_manager = None self._started = False def _onStreamDownloadProgress(self, bytes_received: int, bytes_total: int) -> None: # An MJPG stream is (for our purpose) a stream of concatenated JPG images. # JPG images start with the marker 0xFFD8, and end with 0xFFD9 if self._image_reply is None: return self._stream_buffer += self._image_reply.readAll() # if len(self._stream_buffer) > 2000000: # No single camera frame should be 2 Mb or larger # Logger.log("w", "MJPEG buffer exceeds reasonable size. Restarting stream...%d",len(self._stream_buffer)) # self.stop() # resets stream buffer and start index # self.start() # return if self._stream_buffer_start_index == -1: self._stream_buffer_start_index = self._stream_buffer.indexOf( b'\xff\xd8') stream_buffer_end_index = self._stream_buffer.lastIndexOf(b'\xff\xd9') # If this happens to be more than a single frame, then so be it; the JPG decoder will # ignore the extra data. We do it like this in order not to get a buildup of frames if self._stream_buffer_start_index != -1 and stream_buffer_end_index != -1: jpg_data = self._stream_buffer[ self._stream_buffer_start_index:stream_buffer_end_index + 2] self._stream_buffer = self._stream_buffer[stream_buffer_end_index + 2:] self._stream_buffer_start_index = -1 self._image.loadFromData(jpg_data) if self._image.rect() != self._image_rect: self.imageSizeChanged.emit() self.update()
class NetworkMJPGImage(QQuickPaintedItem): def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self._stream_buffer = QByteArray() self._stream_buffer_start_index = -1 self._network_manager = None # type: QNetworkAccessManager self._image_request = None # type: QNetworkRequest self._image_reply = None # type: QNetworkReply self._image = QImage() self._image_rect = QRect() self._source_url = QUrl() self._started = False self._mirror = False self.setAntialiasing(True) ## Ensure that close gets called when object is destroyed def __del__(self) -> None: self.stop() def paint(self, painter: "QPainter") -> None: if self._mirror: painter.drawImage(self.contentsBoundingRect(), self._image.mirrored()) return painter.drawImage(self.contentsBoundingRect(), self._image) def setSourceURL(self, source_url: "QUrl") -> None: self._source_url = source_url self.sourceURLChanged.emit() if self._started: self.start() def getSourceURL(self) -> "QUrl": return self._source_url sourceURLChanged = pyqtSignal() source = pyqtProperty(QUrl, fget=getSourceURL, fset=setSourceURL, notify=sourceURLChanged) def setMirror(self, mirror: bool) -> None: if mirror == self._mirror: return self._mirror = mirror self.mirrorChanged.emit() self.update() def getMirror(self) -> bool: return self._mirror mirrorChanged = pyqtSignal() mirror = pyqtProperty(bool, fget=getMirror, fset=setMirror, notify=mirrorChanged) imageSizeChanged = pyqtSignal() @pyqtProperty(int, notify=imageSizeChanged) def imageWidth(self) -> int: return self._image.width() @pyqtProperty(int, notify=imageSizeChanged) def imageHeight(self) -> int: return self._image.height() @pyqtSlot() def start(self) -> None: self.stop() # Ensure that previous requests (if any) are stopped. if not self._source_url: Logger.log("w", "Unable to start camera stream without target!") return auth_data = "" if self._source_url.userInfo(): # move auth data to basic authorization header auth_data = base64.b64encode( self._source_url.userInfo().encode()).decode("utf-8") authority = self._source_url.authority() self._source_url.setAuthority(authority.rsplit("@", 1)[1]) self._image_request = QNetworkRequest(self._source_url) self._image_request.setAttribute( QNetworkRequest.FollowRedirectsAttribute, True) if auth_data: self._image_request.setRawHeader(b"Authorization", ("basic %s" % auth_data).encode()) if self._source_url.scheme().lower() == "https": # ignore SSL errors (eg for self-signed certificates) ssl_configuration = QSslConfiguration.defaultConfiguration() ssl_configuration.setPeerVerifyMode(QSslSocket.VerifyNone) self._image_request.setSslConfiguration(ssl_configuration) if self._network_manager is None: self._network_manager = QNetworkAccessManager() self._image_reply = self._network_manager.get(self._image_request) self._image_reply.downloadProgress.connect( self._onStreamDownloadProgress) self._started = True @pyqtSlot() def stop(self) -> None: self._stream_buffer = QByteArray() self._stream_buffer_start_index = -1 if self._image_reply: try: try: self._image_reply.downloadProgress.disconnect( self._onStreamDownloadProgress) except Exception: pass if not self._image_reply.isFinished(): self._image_reply.close() except Exception as e: # RuntimeError pass # It can happen that the wrapped c++ object is already deleted. self._image_reply = None self._image_request = None self._network_manager = None self._started = False def _onStreamDownloadProgress(self, bytes_received: int, bytes_total: int) -> None: # An MJPG stream is (for our purpose) a stream of concatenated JPG images. # JPG images start with the marker 0xFFD8, and end with 0xFFD9 if self._image_reply is None: return self._stream_buffer += self._image_reply.readAll() if (len(self._stream_buffer) > 5000000): # No single camera frame should be 5 MB or larger Logger.log( "w", "MJPEG buffer exceeds reasonable size. Restarting stream...") self.stop() # resets stream buffer and start index self.start() return if self._stream_buffer_start_index == -1: self._stream_buffer_start_index = self._stream_buffer.indexOf( b"\xff\xd8") stream_buffer_end_index = self._stream_buffer.lastIndexOf(b"\xff\xd9") # If this happens to be more than a single frame, then so be it; the JPG decoder will # ignore the extra data. We do it like this in order not to get a buildup of frames if self._stream_buffer_start_index != -1 and stream_buffer_end_index != -1: jpg_data = self._stream_buffer[ self._stream_buffer_start_index:stream_buffer_end_index + 2] self._stream_buffer = self._stream_buffer[stream_buffer_end_index + 2:] self._stream_buffer_start_index = -1 self._image.loadFromData(jpg_data) if self._image.rect() != self._image_rect: self.imageSizeChanged.emit() self.update()
class NetworkMJPGImage(QQuickPaintedItem): def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self._stream_buffer = QByteArray() self._stream_buffer_start_index = -1 self._network_manager = None # type: QNetworkAccessManager self._image_request = None # type: QNetworkRequest self._image_reply = None # type: QNetworkReply self._image = QImage() self._image_rect = QRect() self._source_url = QUrl() self._started = False self._mirror = False self.setAntialiasing(True) ## Ensure that close gets called when object is destroyed def __del__(self) -> None: self.stop() def paint(self, painter: "QPainter") -> None: if self._mirror: painter.drawImage(self.contentsBoundingRect(), self._image.mirrored()) return painter.drawImage(self.contentsBoundingRect(), self._image) def setSourceURL(self, source_url: "QUrl") -> None: self._source_url = source_url self.sourceURLChanged.emit() if self._started: self.start() def getSourceURL(self) -> "QUrl": return self._source_url sourceURLChanged = pyqtSignal() source = pyqtProperty(QUrl, fget = getSourceURL, fset = setSourceURL, notify = sourceURLChanged) def setMirror(self, mirror: bool) -> None: if mirror == self._mirror: return self._mirror = mirror self.mirrorChanged.emit() self.update() def getMirror(self) -> bool: return self._mirror mirrorChanged = pyqtSignal() mirror = pyqtProperty(bool, fget = getMirror, fset = setMirror, notify = mirrorChanged) imageSizeChanged = pyqtSignal() @pyqtProperty(int, notify = imageSizeChanged) def imageWidth(self) -> int: return self._image.width() @pyqtProperty(int, notify = imageSizeChanged) def imageHeight(self) -> int: return self._image.height() @pyqtSlot() def start(self) -> None: self.stop() # Ensure that previous requests (if any) are stopped. if not self._source_url: Logger.log("w", "Unable to start camera stream without target!") return self._started = True self._image_request = QNetworkRequest(self._source_url) if self._network_manager is None: self._network_manager = QNetworkAccessManager() self._image_reply = self._network_manager.get(self._image_request) self._image_reply.downloadProgress.connect(self._onStreamDownloadProgress) @pyqtSlot() def stop(self) -> None: self._stream_buffer = QByteArray() self._stream_buffer_start_index = -1 if self._image_reply: try: try: self._image_reply.downloadProgress.disconnect(self._onStreamDownloadProgress) except Exception: pass if not self._image_reply.isFinished(): self._image_reply.close() except Exception as e: # RuntimeError pass # It can happen that the wrapped c++ object is already deleted. self._image_reply = None self._image_request = None self._network_manager = None self._started = False def _onStreamDownloadProgress(self, bytes_received: int, bytes_total: int) -> None: # An MJPG stream is (for our purpose) a stream of concatenated JPG images. # JPG images start with the marker 0xFFD8, and end with 0xFFD9 if self._image_reply is None: return self._stream_buffer += self._image_reply.readAll() if len(self._stream_buffer) > 2000000: # No single camera frame should be 2 Mb or larger Logger.log("w", "MJPEG buffer exceeds reasonable size. Restarting stream...") self.stop() # resets stream buffer and start index self.start() return if self._stream_buffer_start_index == -1: self._stream_buffer_start_index = self._stream_buffer.indexOf(b'\xff\xd8') stream_buffer_end_index = self._stream_buffer.lastIndexOf(b'\xff\xd9') # If this happens to be more than a single frame, then so be it; the JPG decoder will # ignore the extra data. We do it like this in order not to get a buildup of frames if self._stream_buffer_start_index != -1 and stream_buffer_end_index != -1: jpg_data = self._stream_buffer[self._stream_buffer_start_index:stream_buffer_end_index + 2] self._stream_buffer = self._stream_buffer[stream_buffer_end_index + 2:] self._stream_buffer_start_index = -1 self._image.loadFromData(jpg_data) if self._image.rect() != self._image_rect: self.imageSizeChanged.emit() self.update()
class Uart(QSerialPort): signal_update_standard_gui = pyqtSignal(int) def __init__(self, parent=None): super(Uart, self).__init__(parent) # Qt 串口类 # self.com = QSerialPort() self.comParity = (QSerialPort.NoParity, QSerialPort.EvenParity, QSerialPort.OddParity, QSerialPort.SpaceParity, QSerialPort.MarkParity) self.list_of_msg = list() # 图像类 self.img = QPixmap() self.imgHeight = 80 self.imgWidth = 60 self.img_rx_data = QByteArray() self.totalImgSize = self.imgHeight * self.imgWidth # 上位机改参数类 self.ready_to_get_paras = False # self.imgrxData = bytearray() # self.pararxData = bytearray() # 标准模式类 self.standard_rx_data = QByteArray() self.change_paras = dict() # 上位机改参数字典 self.watch_paras = dict() # 上位机看参数 self.wave_paras = dict() # 波形字典 # 串口普通模式发送数据 def com_send_data(self, tx_data: str, is_hex: bool, codetype: str): if len(tx_data) == 0: return if not is_hex: self.write(tx_data.encode(codetype)) else: data = tx_data.replace(' ', '') # 如果16进制不是偶数个字符, 去掉最后一个, [ ]左闭右开 if len(data) % 2 == 1: data = data[0:len(data) - 1] # 如果遇到非16进制字符 # if data.isalnum() is False: # QMessageBox.critical(self, '错误', '包含非十六进制数') # try: hex_data = binascii.a2b_hex(data) # except: # QMessageBox.critical(self, '错误', '转换编码错误') # 发送16进制数据, 发送格式如 ‘31 32 33 41 42 43’, 代表'123ABC' # try: self.write(hex_data) # except: # QMessageBox.critical(self, '异常', '十六进制发送错误') return # 串口改参数模式发送函数 def com_send_change(self, name: str, tx_data_index: str, tx_data_value: str): if self.isOpen(): # self.paras.value = self.para_value.text() # print(self.index) tx_data0 = b'\xb1' # self.para_value.setText(tx_data_value) if tx_data_index.isalnum() and tx_data_value.isalnum(): self.write(tx_data0 + tx_data_index.encode() + b' ' + tx_data_value.encode() + b'\n\x00') self.change_paras[name] = tx_data_value # print("sendParasToMCU") # 串口接收模式处理函数 def com_receive_normal(self, is_hex: bool, code_type: str) -> str: rx_data = bytes(self.readAll()) if not is_hex: # code_type = selfboBox_codetype.currentText() # self.textEdit_Recive.insertPlainText(rx_data.decode(code_type, errors='replace')) return rx_data.decode(code_type, errors='replace') else: data = binascii.b2a_hex(rx_data).decode('ascii') # re 正则表达式 (.{2}) 匹配两个字母 hex_str = ' 0x'.join(re.findall('(.{2})', data)) # 补齐第一个 0x hex_str = '0x' + hex_str + ' ' return hex_str # 串口图像模式处理函数 def com_receive_image(self, cb_index, extra_bytes_len) -> (QBitmap, tuple): if len(self.img_rx_data) == 0: self.img_rx_data = self.readAll() # print(type(self.imgrxData)) if self.img_rx_data[:2] != b'\x01\xfe': # 不是图像的起始位 self.img_rx_data.clear() return None else: # self.imgrxData=self.imgrxData[2:] return None else: self.img_rx_data += self.readAll() # if self.imgrxData[:2]==b'\x01\xfe' and self.imgrxData[-2:]==b'\xfe\x01': if len( self.img_rx_data ) >= self.totalImgSize + 2 + extra_bytes_len: # 校验位两位,其余14位为传的数据 self.clear() # cb_index = selfboBox_imgType.currentIndex() extra_data = tuple(bytes( self.img_rx_data[2:2 + extra_bytes_len])) # 14位额外数据 # print(type( self.label_img.extra_data[0])) # print(self.label_img.extra_data) if cb_index == 0: # 二值化图像 self.img = QBitmap.fromData( QSize(self.imgWidth, self.imgHeight), bytes(self.img_rx_data[2 + extra_bytes_len:]), QImage.Format_Mono) elif cb_index == 1: # 灰度图像 # imgbytes = bytes(self.imgrxData[2:]) # self.img = QImage(imgbytes, self.imgWidth,self.imgHeight, QImage.Format_Mono) imgbytes = bytes([ 255 if int.from_bytes(b, 'little') > 0 else 0 for b in self.img_rx_data[2 + extra_bytes_len:] ]) self.img = QBitmap.fromImage( QImage(imgbytes, self.imgWidth, self.imgHeight, QImage.Format_Grayscale8)) # import numpy as np # a=np.frombuffer(bytes(self.imgrxData[2:]),dtype=np.uint8)*128 # imgbytes=bytes(a) # OpenCVUse.process(imgbytes, self.imgHeight, self.imgWidth) # self.label_img.setPixmap(self.img) self.img_rx_data.clear() return self.img, extra_data # 串口其他模式处理函数 def com_receive_standard(self): rx_data = self.readAll() self.standard_rx_data += rx_data while True: index = self.standard_rx_data.indexOf(b'\x00') if index < 0: # 直到self.standard_rx_data没有'\x00'跳出循环 break # rx_data.resize(index) standard_rx_data_temp = QByteArray(self.standard_rx_data[:index]) self.standard_rx_data = self.standard_rx_data[index + 1:] if len(standard_rx_data_temp) <= 0: continue # self.standard_rx_data.resize(self.standard_rx_data.indexOf(b'\x00')) self.list_of_msg = standard_rx_data_temp[1:].split('\n') # 字符串列表 msg = standard_rx_data_temp[0] # self.standard_rx_data.clear() if msg == b'\xa0': # 看参数模式 self.add_to_dict(self.watch_paras, self.list_of_msg) self.signal_update_standard_gui.emit(0) elif msg == b'\xa8': # 波形模式 self.add_to_dict(self.wave_paras, self.list_of_msg) self.signal_update_standard_gui.emit(2) elif msg == b'\xb2': # 改参数模式,读取参数 self.add_to_dict(self.change_paras, self.list_of_msg) self.signal_update_standard_gui.emit(1) elif msg == b'\xb0': # 改参数模式,成功修改参数 self.signal_update_standard_gui.emit(-1) # 将字符串添加到对应的字典中 @staticmethod def add_to_dict(dic: dict, list_of_msg: list): for entry in list_of_msg: if entry != b'': try: key, value = bytes(entry).split(b':', 1) dic[key.decode(errors='ignore')] = value.decode( errors='ignore') except ValueError: pass
class Ui(QtWidgets.QMainWindow): def __init__(self, *args, **kwargs): super(Ui, self).__init__(*args, **kwargs) uic.loadUi('terminal_display.ui', self) self.serialData = QByteArray().append("created ") self.receivedData = QByteArray() self.transmitData = QByteArray() self.serialPort = QtSerialPort.QSerialPort() self.serialPort.setPortName("COM10") self.serialPort.setBaudRate(115200) self.serialPort.setFlowControl(self.serialPort.NoFlowControl) self.serialPort.setStopBits(self.serialPort.OneStop) self.serialPort.readyRead.connect(self.onreadyread) self.serialPort.bytesWritten.connect(self.onbyteswritten) ports = QtSerialPort.QSerialPortInfo.availablePorts() print(ports) for eachPort in ports: print(eachPort.portName()) print("open : ", self.serialPort.open(QtCore.QIODevice.ReadWrite), self.serialPort.portName()) self.packet = b'' self.packetCounter = 0 palette = QPalette() palette.setColor(QPalette.Window, QColor(53, 53, 53)) palette.setColor(QPalette.WindowText, QColor(255, 255, 255)) palette.setColor(QPalette.Base, QColor(25, 25, 25)) palette.setColor(QPalette.AlternateBase, QColor(53, 53, 53)) palette.setColor(QPalette.ToolTipBase, QColor(255, 255, 255)) palette.setColor(QPalette.ToolTipText, QColor(255, 255, 255)) palette.setColor(QPalette.Text, QColor(255, 255, 255)) palette.setColor(QPalette.Button, QColor(53, 53, 53)) palette.setColor(QPalette.ButtonText, QColor(255, 255, 255)) palette.setColor(QPalette.BrightText, QColor(255, 255, 255)) palette.setColor(QPalette.Link, QColor(42, 130, 218)) palette.setColor(QPalette.Highlight, QColor(42, 130, 218)) palette.setColor(QPalette.HighlightedText, QColor(0, 0, 0)) app.setPalette(palette) ''' self.testTimer = QTimer() self.testTimer.setInterval(10) self.testTimer.timeout.connect(self.timeToSend) self.i=0 self.counter=0 self.formattedi="" self.bytearrayToSend=QByteArray(4,'a') self.testTimer.start() ''' self.show() def timeToSend(self): self.bytearrayToSend.clear() formattedi = '%04d' % self.i self.bytearrayToSend.append(formattedi) print("go ", self.formattedi) print(self.bytearrayToSend) self.serialPort.writeData(self.bytearrayToSend) self.i = (self.i + 1) % 256 def onbyteswritten(self, bytes): # self.serialPort.flush() # print("onbyteswritten",bytes) # print("bytestowrite",self.serialPort.bytesToWrite()) # print(self.serialPort.readBufferSize()) # print() pass def onreadyread(self): # self.serialPort.flush() self.receivedData = self.serialPort.readAll() while len(self.receivedData) > 64: index = self.receivedData.indexOf(b'\x14', 0) print("index : ", index, "len : ", len(self.packet)) self.packet = self.receivedData[index:index + 64] self.packetCounter += 1 print(self.packetCounter, "th packet", self.packet) print("remaining stream : ", len(self.receivedData), self.receivedData) self.receivedData = self.receivedData[index + 64:] print("after strip : ", len(self.receivedData), self.receivedData) if len(self.packet) == 64: self.parse() else: print("packet size miss, skip.") print() def parse(self): year = int.from_bytes(self.packet[0], "big") month = int.from_bytes(self.packet[1], "big") day = int.from_bytes(self.packet[2], "big") hour = int.from_bytes(self.packet[3], "big") minute = int.from_bytes(self.packet[4], "big") second = int.from_bytes(self.packet[5], "big") print(year, month, day, hour, minute, second) date = QDate(year + 2000, month, day) time = QTime(hour, minute, second) self.dateTimeEdit.setDate(date) self.dateTimeEdit.setTime(time) [index, gyrox, gyroy, gyroz, accx, accy, accz, magx, magy, magz, ch1_volt, ch1_amp, ch2_volt, ch2_amp] = \ struct.unpack("iiiiiiiiiififi", self.packet[8:64]) print("stream index : ", index) print("gyro : ", gyrox, gyroy, gyroz) print("acc : ", accx, accy, accz) print("mag : ", magx, magy, magz) print("ch1 : ", ch1_volt, ch1_amp) print("ch2 : ", ch2_volt, ch2_amp) self.Index_lineEdit.setText(str(index)) self.lineEdit_Status_gyrox.setText(str(gyrox)) self.lineEdit_Status_gyroy.setText(str(gyroy)) self.lineEdit_Status_gyroz.setText(str(gyroz)) self.lineEdit_Status_accx.setText(str(accx)) self.lineEdit_Status_accy.setText(str(accy)) self.lineEdit_Status_accz.setText(str(accz)) self.lineEdit_Status_magx.setText(str(magx)) self.lineEdit_Status_magy.setText(str(magy)) self.lineEdit_Status_magz.setText(str(magz)) self.lineEdit_Ch1_vol.setText(str(ch1_volt)) self.lineEdit_Ch1_amp.setText(str(ch1_amp)) self.lineEdit_Ch2_vol.setText(str(ch2_volt)) self.lineEdit_Ch2_amp.setText(str(ch2_amp)) def commandstart(self): print("command start") self.serialPort.writeData(b'\x01\x00') def commandstop(self): print("command stop") self.serialPort.writeData(b'\x00\x00') def SingleModeClicked(self, On): if On: print("Single mode on") self.serialPort.writeData(b'\x02\x00') else: print("Single mode off") def MultiModeClicked(self, On): if On: print("Multimode on") self.serialPort.writeData(b'\x02\x01') else: print("Multimode off") def changeIntensityValue(self, value): print("intensity value ", value) self.receivedData.clear() print("data to append : ", QByteArray.number(value, 16)) print("QByteArray after append") self.receivedData.append(QByteArray.fromHex(QByteArray.number(3, 16))) self.receivedData.append( QByteArray.fromHex(QByteArray.number(value, 16))) print(self.receivedData) self.serialPort.writeData(self.receivedData) self.receivedData.clear()
class ProcessHandler(QObject): commandReceived = pyqtSignal(str) commandSent = pyqtSignal(str) processFinished = pyqtSignal() processError = pyqtSignal(str) def __init__(self, executable, parent=None): QObject.__init__(self, parent) self.executable = executable def run(self): self.process = QProcess() self.process.readyReadStandardOutput.connect(self.handleInput) self.process.setReadChannel(QProcess.StandardOutput) self.process.closeReadChannel(QProcess.StandardError) self.process.finished.connect(self.processFinished) self.pendingInput = QByteArray() self.in_message = False self.inputExpected = 0 self.pendingOutput = QByteArray() self.process.start(self.executable) # On Qt 5.6 and later, we can use the errorOccurred signal instead. if not self.process.waitForStarted(-1): self.processError.emit("The application quit unexpectedly.") def quit(self): print("Terminating %i" % self.process.processId()) self.process.closeReadChannel(QProcess.StandardOutput) self.process.closeReadChannel(QProcess.StandardError) self.process.closeWriteChannel() self.process.terminate() self.process.waitForFinished() self.thread().quit() def handleInput(self): self.pendingInput += self.process.readAllStandardOutput() try: while self.pendingInput.size() > 0: if not self.in_message: space = self.pendingInput.indexOf(b" ") if space == -1: return # Specify UTF-8 instead of falling back on something implicit. self.inputExpected = int( str(self.pendingInput.left(space), "utf8")) # Examine the rest of the input. self.pendingInput = self.pendingInput.mid(space + 1) self.in_message = True # Try to read the rest of the message. if len(self.pendingInput) >= self.inputExpected: command = self.pendingInput.left(self.inputExpected) self.pendingInput = self.pendingInput.mid( self.inputExpected) self.in_message = False self.inputExpected = 0 self.commandReceived.emit(str(command, "utf8")) elif self.process.bytesAvailable() > 0: self.pendingInput += self.process.readAllStandardOutput() else: return except ValueError: self.processError.emit(str(self.pendingInput, "utf8")) def handleOutput(self, message): # Write the length of the message and the message itself. message = "%i %s" % (len(message), message) self.pendingOutput += QByteArray(bytes(message, "utf8")) while self.pendingOutput.size() > 0: written = self.process.write(self.pendingOutput) if written == -1: self.processError.emit("Failed to write to application.") return # Handle the rest of the output. self.pendingOutput = self.pendingOutput.mid(written) self.commandSent.emit(message)