一、思路
使用serial库的read相关的方法读取串口的内容,并且显示在我们的textBrowser上面。
二、实现
2.1 构建文本信号
class data_class(QObject):
text = Signal(QTextBrowser,str)
我们自定义一个文本信号,且信号内容包含了一个QTextBrowser类和一个str类型的数据。后续我们会将这个信号和textBrowser的text显示相连接,再绑定对应的槽函数。
2.2 数据接收线程
def Serial_Data_RX_Thread_Function(self):
while True:
try:
if self.con.serial_class.serial.is_open: # 串口打开则接收数据
get_data = self.con.serial_class.serial.readline() # 读取串口数据
self.time_data = (QtCore.QDateTime.currentDateTime().toString(
'yyyy/MM/dd HH:mm:ss') ).encode('utf-8')
if get_data.decode('utf-8'): # 将str数据转换成 utf-8格式判断其是否不为空
if self.con.ui.ui.checkBox.isChecked():
self.con.data_class.text.emit(self.con.ui.ui.log_textBrowser,"["+
self.time_data.decode('utf-8')+"] 收 👉 " +get_data.decode('utf-8'))
else:
# 信号发送数据,信号绑定槽函数就会执行槽函数
self.con.data_class.text.emit(self.con.ui.ui.log_textBrowser , "收 👉 " + get_data.decode('utf-8'))
if self.con.slot_con.save_path != None:
with open(self.con.slot_con.save_path + "/log.txt", 'a') as file:
file.write( self.time_data.decode('utf-8')+get_data.decode('utf-8'))
except Exception as error:
print(error)
创建一个线程去接收串口的数据,若串口打开就接收数据,使用readline方法,读取整行数据,且将读取到的数据放入一个列表当中,再将其转化成utf-8的格式。其中的一些逻辑包含了后续的”时间戳“和“日志保存”功能,可以先暂时忽略。最后将读取到的数据发送出去,调用emit方法,变量为我们的textBrowser和数据列表(注:是字符串格式)
2.3 信号接收的槽函数
@staticmethod
def Uart_RX_Data_Signal_Print_Data_to_Gui(my_QTextBrowser, text):
my_QTextBrowser.append(str(text)) # 添加数据
my_QTextBrowser.ensureCursorVisible() # 确保光标可见
my_QTextBrowser.moveCursor(my_QTextBrowser.textCursor().End) # 将光标移动到最后
#代码参考自网上的大神,但是找不到时哪个了,😓
该槽函数,传入一个texrBrower类变量和一个文本变量,跟我们的定义的信号时一致的。将文本信息添加到我们的显示页面当中,确保光标时可见的,且光标移到最后,更加方便我们阅读新的信息。(注:在使用过程中会出现一个bug,如果发送方发送的数据时无间隔的,这边就会有一串很长很长的数据,因为readline时读取整行,程序没办法判断该行是否结束😓,还在改进当中)
2.4 创建接收线程
self.Serial_Data_RX_Thread = threading.Thread(target=self.Serial_Data_RX_Thread_Function, daemon=True)
该线程绑定的函数时数据接收的函数,该线程在串口打开的时候就开启!
三、总结
上述是实现的主要方法和步骤,做一下思路的总结。因为我们这个textBrowser其实是需要自己定义信号的,定义信号是什么样子的 需要什么参数和内容,不像pushbutton类,信号是clicked,不用自己定义。其次,我们要持续不断的接收数据,所以启动了一个线程来执行数据的读取函数。