|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
自学python,写了个串口工具,但是一旦连续接收数据多了之后,程序就会崩溃。
不知道是何原因,请小伙伴们帮忙找下原因。
另外代码写的不合理的地方,也希望帮忙指出,谢谢。
出错截图如下图。右边是网上找的串口工具,连续不断的给右边(自己写的)程序发数据,两条消息间隔30ms。
没传多久就会出现如图的停止工作的情况。
出错截图
Pthon3 + PyQT
helloU.py# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'helloU.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(562, 437)
MainWindow.setMinimumSize(QtCore.QSize(562, 437))
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setEnabled(True)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout_2 = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout_2.setObjectName("gridLayout_2")
self.gridLayout = QtWidgets.QGridLayout()
self.gridLayout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
self.gridLayout.setObjectName("gridLayout")
self.sendLineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.sendLineEdit.setObjectName("sendLineEdit")
self.gridLayout.addWidget(self.sendLineEdit, 2, 0, 1, 7)
self.dataBits = QtWidgets.QComboBox(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.dataBits.sizePolicy().hasHeightForWidth())
self.dataBits.setSizePolicy(sizePolicy)
self.dataBits.setMinimumSize(QtCore.QSize(50, 20))
self.dataBits.setMaximumSize(QtCore.QSize(50, 20))
self.dataBits.setObjectName("dataBits")
self.gridLayout.addWidget(self.dataBits, 0, 4, 1, 1)
self.sendBtn = QtWidgets.QPushButton(self.centralwidget)
self.sendBtn.setObjectName("sendBtn")
self.gridLayout.addWidget(self.sendBtn, 3, 0, 1, 1)
self.rcvBrowser = QtWidgets.QTextBrowser(self.centralwidget)
self.rcvBrowser.setObjectName("rcvBrowser")
self.gridLayout.addWidget(self.rcvBrowser, 1, 0, 1, 7)
self.parityMode = QtWidgets.QComboBox(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.parityMode.sizePolicy().hasHeightForWidth())
self.parityMode.setSizePolicy(sizePolicy)
self.parityMode.setMinimumSize(QtCore.QSize(60, 20))
self.parityMode.setMaximumSize(QtCore.QSize(60, 20))
self.parityMode.setObjectName("parityMode")
self.gridLayout.addWidget(self.parityMode, 0, 3, 1, 1)
self.stopBits = QtWidgets.QComboBox(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.stopBits.sizePolicy().hasHeightForWidth())
self.stopBits.setSizePolicy(sizePolicy)
self.stopBits.setMinimumSize(QtCore.QSize(50, 20))
self.stopBits.setMaximumSize(QtCore.QSize(50, 20))
self.stopBits.setObjectName("stopBits")
self.gridLayout.addWidget(self.stopBits, 0, 5, 1, 1)
self.baudLineEdit = QtWidgets.QLineEdit(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.baudLineEdit.sizePolicy().hasHeightForWidth())
self.baudLineEdit.setSizePolicy(sizePolicy)
self.baudLineEdit.setMinimumSize(QtCore.QSize(80, 20))
self.baudLineEdit.setMaximumSize(QtCore.QSize(80, 20))
self.baudLineEdit.setText("")
self.baudLineEdit.setObjectName("baudLineEdit")
self.gridLayout.addWidget(self.baudLineEdit, 0, 2, 1, 1)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.gridLayout.addItem(spacerItem, 0, 6, 1, 1)
self.openButton = QtWidgets.QPushButton(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.openButton.sizePolicy().hasHeightForWidth())
self.openButton.setSizePolicy(sizePolicy)
self.openButton.setMinimumSize(QtCore.QSize(80, 20))
self.openButton.setMaximumSize(QtCore.QSize(80, 20))
self.openButton.setObjectName("openButton")
self.gridLayout.addWidget(self.openButton, 0, 0, 1, 1)
self.portNum = QtWidgets.QComboBox(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.portNum.sizePolicy().hasHeightForWidth())
self.portNum.setSizePolicy(sizePolicy)
self.portNum.setMinimumSize(QtCore.QSize(80, 20))
self.portNum.setMaximumSize(QtCore.QSize(80, 20))
self.portNum.setObjectName("portNum")
self.gridLayout.addWidget(self.portNum, 0, 1, 1, 1)
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.gridLayout.addItem(spacerItem1, 3, 3, 1, 4)
self.HexCheckBox = QtWidgets.QCheckBox(self.centralwidget)
self.HexCheckBox.setObjectName("HexCheckBox")
self.gridLayout.addWidget(self.HexCheckBox, 3, 1, 1, 1)
self.NewLineCheckBox = QtWidgets.QCheckBox(self.centralwidget)
self.NewLineCheckBox.setObjectName("NewLineCheckBox")
self.gridLayout.addWidget(self.NewLineCheckBox, 3, 2, 1, 1)
self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 562, 23))
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)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.sendBtn.setText(_translate("MainWindow", "Send"))
self.openButton.setText(_translate("MainWindow", "OPEN"))
self.HexCheckBox.setText(_translate("MainWindow", "HEX"))
self.NewLineCheckBox.setText(_translate("MainWindow", "NewLine"))
SerialHandle.py#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import sys
import threading
import time
import serial
import binascii
import logging
logging.basicConfig(level=logging.INFO)
class SerialHandle(object):
def __init__(self, Port="COM3", BaudRate="9600", ByteSize="8", Parity="N", Stopbits="1"):
'''
初始化一些参数
:param Port:
:param BaudRate:
:param ByteSize:
:param Parity:
:param Stopbits:
:return:
'''
self.l_serial = None
self.alive = False
self.portNum = Port
self.baudrate = BaudRate
self.bytesize = ByteSize
self.parity = Parity
self.stopbits = Stopbits
self.receiveData = ""
def start(self):
'''
打开串口
:return:
'''
self.l_serial = serial.Serial()
self.l_serial.port = self.portNum
self.l_serial.baudrate = self.baudrate
self.l_serial.bytesize = int(self.bytesize)
self.l_serial.parity = self.parity
self.l_serial.stopbits = int(self.stopbits)
self.l_serial.timeout = 2
try:
self.l_serial.open()
if self.l_serial.isOpen():
self.alive = True
except Exception as e:
self.alive = False
logging.error(e)
def stop(self):
'''
关闭串口
:return:
'''
self.alive = False
if self.l_serial.isOpen():
self.l_serial.close()
# 获取COM号列表
def port_list(self):
comlist = []
port_list = list(serial.tools.list_ports.comports())
for port in port_list:
comlist.append(port[0])
return comlist
def read(self):
'''
循环读取串口的数据
:return:
'''
isRcved = False
timeRcved = 0
while self.alive:
try:
number = self.l_serial.inWaiting()
if number:
isRcved = True
timeRcved = int(round(time.time() * 1000))
self.receiveData += self.l_serial.read(number).decode()#.replace(binascii.unhexlify("00"), "")
#print(self.receiveData)
#print("rcv data: %s" % self.l_serial.read(number).decode())
except Exception as e:
logging.error(e)
if isRcved == True :
if (int(round(time.time() * 1000)) - timeRcved)>10:
print(self.receiveData)
isRcved = False
self.receiveData = ""
def dataReceiveAndProcess(self, func):
try:
thread_read = threading.Thread(target=self._dataRecevie, args=(func, ))
thread_read.setDaemon(True)
thread_read.start()
except BaseException as e:
print("error:",e)
def _dataRecevie(self, func):
'''
循环读取串口的数据
:return:
'''
isRcved = False
timeRcved = 0
while self.alive:
number = self.l_serial.inWaiting()
if number:
logging.info('receive data\n')
isRcved = True
timeRcved = int(round(time.time() * 1000))
self.receiveData += self.l_serial.read(number).decode()#.replace(binascii.unhexlify("00"), "")
#print(self.receiveData)
#print("rcv data: %s" % self.l_serial.read(number).decode())
if isRcved == True :
if (int(round(time.time() * 1000)) - timeRcved)>10:
logging.info('process data\n')
#print(self.receiveData)
func(self.receiveData)
isRcved = False
self.receiveData = ""
def sendData(self, data, isHex=False, isNewLine=False):
'''
发送数据
:param data: self.sendLineEdit.text()
:param isHex: self.HexCheckBox.checkState()
:param isNewLine: self.NewLineCheckBox.checkState()
:return:
'''
if data != "":
if (isHex == False):
# 字符串发送
if isNewLine:
data = data + "\r\n"
inputData = data.encode('utf-8')
else:
# 十六进制发送
data = data.strip() # 删除前后的空格
sendList = []
while data != "":
try:
# int() 函数用于将一个字符串或数字转换为整型。
num = int(data[0:2], 16)
except ValueError:
print("input hex data!")
#QMessageBox.critical(self, 'pycom', '请输入十六进制数据,以空格分开!')
return None
data = data[2:]
data = data.strip()
# 添加到发送列表中
sendList.append(num)
if isNewLine:
sendList.append(0x0d)
sendList.append(0x0a)
inputData = bytes(sendList)
# d = "12abc"
# d = d.encode("ascii")
self.l_serial.write(inputData)
if __name__ == '__main__':
import threading
ser = SerialHandle()
ser.start()
ser.sendData("12 23 34", True)
thread_read = threading.Thread(target=ser.read)
thread_read.setDaemon(True)
thread_read.start()
import time
time.sleep(25)
ser.stop()
main.py#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import sys
import threading
import time
import datetime
import helloU
import SerialHandle
import serial
import serial.tools.list_ports
from PyQt5.QtGui import *
from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox
class SerialDlg(helloU.Ui_MainWindow):
def defaultInit(self):
self.ser = SerialHandle.SerialHandle()
self.serial_receive_count = 0
self.portNum.addItems(self.ser.port_list())
self.baudLineEdit.setText("9600")
self.parityMode.addItems(['None', 'Even', 'Odd', 'Mark', 'Space'])
self.dataBits.addItems(['5', '6', '7', '8'])
self.stopBits.addItems(['1', '1.5', '2'])
self.dataBits.setCurrentText("8")
self.openButton.setText("OPEN")
self.openButton.setStyleSheet("background-color:#4abdac")
self.openButton.setFont(QFont('SansSerif', 15, QFont.Bold))
self.openButton.setAutoFillBackground(True)
self.openButton.clicked.connect(self.OpenSerial)
self.sendBtn.clicked.connect(self.SendData)
self.sendBtn.setDisabled(True)
# 打开串口
def OpenSerial(self):
if self.openButton.text() == "OPEN":
self.portNum.setDisabled(True)
self.baudLineEdit.setDisabled(True)
self.parityMode.setDisabled(True)
self.dataBits.setDisabled(True)
self.stopBits.setDisabled(True)
self.sendBtn.setDisabled(False)
self.port = self.portNum.currentText()
self.baudrate = self.baudLineEdit.text()
ParityValue = self.parityMode.currentText()
self.parity = ParityValue[0]
self.bytesize = int(self.dataBits.currentText())
self.stopbits = int(self.stopBits.currentText())
self.openButton.setText("CLOSE")
self.openButton.setStyleSheet("background-color:#fc4a1a")
# self.openButton.setAutoFillBackground(True)
self.ser.portNum = self.port
self.ser.baudrate = self.baudrate
self.ser.bytesize = self.bytesize
self.ser.parity = self.parity
self.ser.stopbits = self.stopbits
self.ser.start()
self.ser.dataReceiveAndProcess(self.showDataOnQTextBrowser)
#thread_read = threading.Thread(target=self.ser.read)
#thread_read.setDaemon(True)
#thread_read.start()
elif self.openButton.text() == "CLOSE":
self.ser.stop()
self.openButton.setText("OPEN")
self.openButton.setStyleSheet("background-color:#4abdac")
# self.openButton.setAutoFillBackground(True)
self.portNum.setDisabled(False)
self.baudLineEdit.setDisabled(False)
self.parityMode.setDisabled(False)
self.dataBits.setDisabled(False)
self.stopBits.setDisabled(False)
self.sendBtn.setDisabled(True)
# 发送数据
def SendData(self):
self.ser.sendData(self.sendLineEdit.text(), self.HexCheckBox.checkState(), self.NewLineCheckBox.checkState())
# 数据显示
def showDataOnQTextBrowser(self, data):
self.serial_receive_count += 1
self.rcvBrowser.append("[" + str(datetime.datetime.now()) + " - "+ str(self.serial_receive_count) + "]:\n")
self.rcvBrowser.append(data)
#QTextCursor cursor = self.rcvBrowser.textCursor()
self.rcvBrowser.setTextCursor(self.rcvBrowser.textCursor())
if __name__ == '__main__':
app = QApplication(sys.argv)
MainWindow = QMainWindow()
ui = SerialDlg() #helloU.Ui_MainWindow()
ui.setupUi(MainWindow)
ui.defaultInit()
MainWindow.show()
sys.exit(app.exec_())
对  ,我的archlinux+gnome就没有事,  你再等等吧,python更新后应该会好,还有,别装测试版,bug多 
|
|