# -*- coding:utf-8 -*-
import sys
import serial
import serial.tools.list_ports
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QDialog
from PyQt5.QtWidgets import QMessageBox
from PyQt5.QtCore import QTimer
from PyQt5.uic import loadUi
class Uart(QDialog):
def __init__(self,*args):
super(Uart,self).__init__(*args)
loadUi('uart.ui',self)
self.s1_comboBox_2.setCurrentIndex(10)
self.s1_comboBox_3.setCurrentIndex(2)
self.close_button.setEnabled(False)
self.s5_pushButton_2.setEnabled(False)
self.init()
self.ser = serial.Serial()
self.port_check()
# 接收数据和发送数据数目置零
self.data_num_received = 0
self.s3_lineEdit_1.setText(str(self.data_num_received))
self.data_num_sended = 0
self.s3_lineEdit_2.setText(str(self.data_num_sended))
def init(self):
# 串口检测按钮
self.s1_pushButton_1.clicked.connect(self.port_check)
# 串口信息显示
self.s1_comboBox_1.currentTextChanged.connect(self.port_imf)
# 打开串口按钮
self.open_button.clicked.connect(self.port_open)
# 关闭串口按钮
self.close_button.clicked.connect(self.port_close)
# 发送数据按钮
self.s5_pushButton_2.clicked.connect(self.data_send)
# 定时发送数据
self.timer_send = QTimer()
self.timer_send.timeout.connect(self.data_send)
self.timer_send_cb.stateChanged.connect(self.data_send_timer)
# 定时器接收数据
self.timer = QTimer(self)
self.timer.timeout.connect(self.data_receive)
# 清除发送窗口
self.s5_pushButton_3.clicked.connect(self.send_data_clear)
# 清除接收窗口
self.s5_pushButton_1.clicked.connect(self.receive_data_clear)
# 串口检测
def port_check(self):
# 检测所有存在的串口,将信息存储在字典中
self.Com_Dict = {}
port_list = list(serial.tools.list_ports.comports())
self.s1_comboBox_1.clear()
for port in port_list:
self.Com_Dict["%s" % port[0]] = "%s" % port[1]
self.s1_comboBox_1.addItem(port[0])
if len(self.Com_Dict) == 0:
self.state_label.setText(" 无串口")
# 串口信息
def port_imf(self):
# 显示选定的串口的详细信息
imf_s = self.s1_comboBox_1.currentText()
if imf_s != "":
self.state_label.setText(self.Com_Dict[self.s1_comboBox_1.currentText()])
# 打开串口
def port_open(self):
self.ser.port = self.s1_comboBox_1.currentText()
self.ser.baudrate = int(self.s1_comboBox_2.currentText())
self.ser.bytesize = int(self.s1_comboBox_3.currentText())
self.ser.stopbits = int(self.s1_comboBox_5.currentText())
self.ser.parity = self.s1_comboBox_4.currentText()
try:
self.ser.open()
except:
QMessageBox.critical(self,"Port Error","此串口不能被打开!")
return None
# 打开串口接收定时器,周期为2ms
self.timer.start(2)
if self.ser.isOpen():
self.s5_pushButton_2.setEnabled(True)
self.open_button.setEnabled(False)
self.close_button.setEnabled(True)
self.groupBox_3.setTitle("串口状态(已开启)")
# 关闭串口
def port_close(self):
self.timer.stop()
self.timer_send.stop()
try:
self.ser.close()
except:
pass
self.open_button.setEnabled(True)
self.close_button.setEnabled(False)
self.s5_lineEdit.setEnabled(True)
self.timer_send_cb.setChecked(False)
self.s5_pushButton_2.setEnabled(False)
# 接收数据和发送数据数目置零
self.data_num_received = 0
self.s3_lineEdit_1.setText(str(self.data_num_received))
self.data_num_sended = 0
self.s3_lineEdit_2.setText(str(self.data_num_sended))
self.groupBox_3.setTitle("串口状态(已关闭)")
# 发送数据
def data_send(self):
if self.ser.isOpen():
input_s = self.s4_lineEdit_1.toPlainText()
if input_s != "":
# 非空字符串
if self.hex_send.isChecked():
# hex 发送
input_s = input_s.strip()
send_list = []
while input_s != '':
try:
num = int(input_s[0:2],16)
except ValueError:
QMessageBox.critical(self,'wrong data','请输入十六进制数据,以空格分开!')
return None
input_s = input_s[2:].strip()
send_list.append(num)
input_s = bytes(send_list)
else:
# ascii 发送
input_s = (input_s + '\r\n').encode('utf-8')
num = self.ser.write(input_s)
self.data_num_sended += num
self.s3_lineEdit_2.setText(str(self.data_num_sended))
else:
pass
# 接收数据
def data_receive(self):
try:
num = self.ser.inWaiting()
except:
self.port_close()
return None
if num > 0:
data = self.ser.read(num)
num = len(data)
# hex 显示
if self.hex_receive.checkState():
out_s = ''
for i in range(0,len(data)):
out_s = out_s + '{:02X}'.format(data[i]) + ' '
self.s2_textEdit.insertPlainText(out_s + '\n')
else:
# 串口接收到的字符串为b'123',要转化成unicode字符串才能输出到窗口中去
self.s2_textEdit.insertPlainText(data.decode('iso-8859-1'))
# 统计接收字符的数量
self.data_num_received += num
self.s3_lineEdit_1.setText(str(self.data_num_received))
# 获取到text光标
textCursor = self.s2_textEdit.textCursor()
# 滚动到底部
textCursor.movePosition(textCursor.End)
# 设置光标到text中去
self.s2_textEdit.setTextCursor(textCursor)
else:
pass
# 定时发送数据
def data_send_timer(self):
if self.timer_send_cb.isChecked():
self.timer_send.start(int(self.s5_lineEdit.text()))
self.s5_lineEdit.setEnabled(False)
else:
self.timer_send.stop()
self.s5_lineEdit.setEnabled(True)
# 清除显示
def send_data_clear(self):
self.s4_lineEdit_1.setText("")
def receive_data_clear(self):
self.s2_textEdit.setText("")