解决textctrl控件不实时显示报文信息并且界面会卡住的问题

问题现象描述:textctrl控件不能实时显示报文信息,只能在全部接收之后一次性显示到界面上,当报文信息量较大时,极易造成界面卡死。

原执行界面卡死:
解决textctrl控件不实时显示报文信息并且界面会卡住的问题

解决办法参考文章:如何从子流程标准输出获得结果并在TextCtrl中实时显示它们? (Python 2.7 - wxPython)
http://cn.voidcc.com/question/p-faxdrneo-uv.html

将textctrl控件显示报文内容的功能移到线程进行执行。
代码片段如下:

class LinkThread(Thread):

    def __init__(self, m_textCtrl1, can_device, baud_rate, device_id):
        Thread.__init__(self)
        self.m_textCtrl1 = m_textCtrl1
        self.can_device = can_device
        self.baud_rate = baud_rate
        self.device_id = device_id
        self.start()

    def run(self):
        Timing0 = can_interface.Timing0_dict[self.baud_rate]
        Timing1 = can_interface.Timing1_dict[self.baud_rate]
        vci_initconfig = can_interface.VCI_INIT_CONFIG(0x00000000, 0xFFFFFFFF, 0, 1, Timing0, Timing1, 0)
        open_state = can_interface.open_device(self.can_device, self.device_id, 0)
        if open_state == 0:
            toastone = wx.MessageDialog(None, "打开设备操作失败!", "错误信息提示", wx.YES_DEFAULT | wx.ICON_QUESTION)
            if toastone.ShowModal() == wx.ID_YES:  # 如果点击了提示框的确定按钮
                toastone.Destroy()  # 则关闭提示框
        elif open_state == -1:
            toastone = wx.MessageDialog(None, "USB-CAN设备不存在或USB掉线!", "错误信息提示", wx.YES_DEFAULT | wx.ICON_QUESTION)
            if toastone.ShowModal() == wx.ID_YES:  # 如果点击了提示框的确定按钮
                toastone.Destroy()  # 则关闭提示框
        else:
            # 设置波特率
            pData = can_interface.baud_rate_dict[self.baud_rate]
            can_interface.set_reference(self.can_device, self.device_id, 0, 0, pData)
            # 初始化can通道
            can_interface.ini_can(self.can_device, self.device_id, 0, vci_initconfig)
            # 启动can设备
            start_state = can_interface.start_device(self.can_device, self.device_id, 0)
            if start_state == 0:
                toastone = wx.MessageDialog(None, "打开设备操作失败!", "错误信息提示", wx.YES_DEFAULT | wx.ICON_QUESTION)
                if toastone.ShowModal() == wx.ID_YES:  # 如果点击了提示框的确定按钮
                    toastone.Destroy()  # 则关闭提示框
            elif start_state == -1:
                toastone = wx.MessageDialog(None, "USB-CAN设备不存在或USB掉线!", "错误信息提示", wx.YES_DEFAULT | wx.ICON_QUESTION)
                if toastone.ShowModal() == wx.ID_YES:  # 如果点击了提示框的确定按钮
                    toastone.Destroy()  # 则关闭提示框
            else:
                # 开始接收can报文信息
                count = 0
                while 1:
                    # while count < 50:
                    # 清空缓冲区
                    can_interface.clear_buffer(self.can_device, self.device_id, 0)
                    rxdata = can_interface._RX_CAN_OBJ()
                    while can_interface.get_receive_num(self.can_device, self.device_id, 0) == 0:
                        continue
                    # 接收缓存数量
                    if can_interface.get_receive_num(self.can_device, self.device_id, 0) == 1:
                        if (can_interface.receive_msg(self.can_device, self.device_id, 0, rxdata, 50, 100)):
                            count += 1
                            msg_view_dict = analysis_msg.analyse_msg(rxdata)
                            msg_view_dict["序号"] = (8 - len(str(count))) * "0" + str(count)
                            text_str = "    ".join(["序号:%s" % msg_view_dict["序号"],
                                                    "传输方向:%s" % msg_view_dict["传输方向"],
                                                    "帧ID:%s" % msg_view_dict["帧ID"],
                                                    "帧格式:%s" % msg_view_dict["帧格式"],
                                                    "帧类型:%s" % msg_view_dict["帧类型"],
                                                    "数据(HEX):%s" % msg_view_dict["数据(HEX)"]])
                            self.data = msg_view_dict["数据(HEX)"]
                            wx.CallAfter(self.m_textCtrl1.write, text_str + "\n")
                        else:
                            print("接收缓存区为空")
                    else:
                        print("接收缓存数量大于1")

在原来的Frame下设置按钮触发事件onLink,执行LinkThread线程。

# 设置按钮触发事件
        if self.m_button1.GetLabel() == "连接":
            self.m_button1.Bind(wx.EVT_LEFT_DOWN, self.onLink)
    def onLink(self, event):
        self.link_thread = LinkThread(self.m_textCtrl1, self.can_device, self.baud_rate, self.device_id)
        if self.link_thread:
            self.m_button1.SetLabel("断开")
            self.m_button1.Bind(wx.EVT_LEFT_DOWN, self.onClose)

代码调整之后,textctrl实时显示报文信息并且不会出现界面卡住的运行截图:
解决textctrl控件不实时显示报文信息并且界面会卡住的问题

上一篇:Java注解使用! 转载// 项目中页数这么用,已经很深入了


下一篇:Velocity