利用pyqt工具将CAN总线报文显示在QTextEdit面板上

我试着在一个主程序内实现,但无法启动主窗口,print报文能够在后台显示出来,但是,如果利用QTextEdit.insertPlainText(msg)来插入报文,首先就是面板无法显示报文,其次是,当报文传输一段时间后,程序就自动终止了。(这里面我要讲一下,我是找了两个硬件设备,一个用来发送,一个用来接收,将这两个设备的端口用CAN线连接起来!)

import can
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import time
class can_recv(QThread):   #建立控件窗口
    trigger=pyqtSignal(str)
    def __init__(self):
        super(can_recv,self).__init__()

    def run(self):
        while True:
            mes = mes_recv()
            print(mes)
            self.trigger.emit(str(mes))

def mes_recv():
        bus_rx = can.Bus(bustype='vector', app_name=None, channel=0, bitrate=500000)
        while True:
            mes=bus_rx.recv()
            return mes

def slotStart():
    worker.start()

def slotAdd(f_int):
    while True:
        content1.insertPlainText(f_int)

if __name__=='__main__':
    app=QApplication(sys.argv)
    top=QWidget()
    top.resize(300,120)
    layout = QVBoxLayout(top)
    btn1 = QPushButton('查看报文')
    content1 = QTextEdit()
    layout.addWidget(btn1)
    layout.addWidget(content1)
    worker=can_recv()  #初始化线程
    btn1.clicked.connect(lambda :slotStart())
    worker.trigger.connect(slotAdd)
    top.show()
    sys.exit(app.exec())

运行结果及报错内容如下图:(自动退出的)

img

刚开始我准备在一个主程序内解决,后来发现不行,如果一个主程序既要实现窗口,又要实现CAN数据传输和加载,貌似不大行。我又引入了线程QThread,就是主程序用来建立GUI窗口,分线程用来处理数据,发现又不行。我曾尝试过用can.Listener,这种方式能在后台打印报文,也能够下载监听的报文,但是我不知道该如何将这些报文导入到面板当中,listener类型是列表


logger = can.Logger("C:\\Users\\Desktop\\data_exchange\\logfile1.log")  # save log to asc file
        listeners = [
            print_message, 
            logger,  
        ]
        notifier = can.Notifier(bus_rx, listeners)

我最终的目的就是将后台监听的报文打印到这个面板上

img

第一,bus_rx.recv()后要检测是否读取到了数据,如果没读取到不要emit。
第二,slotAdd函数内把while(True)删掉,insertPlainText保留。(这是引起程序崩溃的原因)

可选优化1:mes_recv函数中的while(True)删掉。
可选优化2:如果can.Bus有阻塞标志位,考虑使用阻塞 可节省CPU。
可选优化3:考虑删除slotAdd槽函数,使用QTextEdit的append槽函数。

请采纳谢谢

创建一个从QTextEdit继承并覆盖并添加必要属性的类