pyqt5+多线程更新tablewidget,程序自动退出,终端无错误提示

本人由于工作需要一个CAN的上位机,自学1个月,用的pyqt5+多线程。我在网上看到说是子线程中不能更新控件,但是实际上我通过重写QThread类,把mainwindow中的的tablewidget1和tablewidget2传进到QThread类中,发现可以更新控件也就没管了。后面出现了程序自动退出的问题,终端没有任何错误提示。于是我分别屏蔽了操作tablewidget1和tablewidget2的代码,发现只操作tablewidget1的话就不会自动退出了,不知道是哪点原因,下面是代码,请求各位技术大大们帮忙看看!

window.py:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file '.\mainwindow.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from canlib import canlib, kvadblib
import threading
import time
import display_widgets
import os
import sys


class CANThread(QtCore.QThread):                      #更新widget
    def __init__(self,name,table_widget1,table_widget2,dbc,select_id):
        super(CANThread, self).__init__()
        self.name = name
        self.Flag=True                                #停止标志位
        self.table_widget1 = table_widget1            #分析窗口1
        self.table_widget2 = table_widget2            #分析窗口2
        self.dbc = dbc
        self.db = None
        self.select_id = select_id

        self.ch = canlib.openChannel(channel=0,flags=canlib.Open.CAN_FD,bitrate=canlib.canFD_BITRATE_500K_80P,data_bitrate=canlib.canFD_BITRATE_2M_80P,)
        self.ch.setBusOutputControl(canlib.canDRIVER_NORMAL)
      
    
    def run(self):
        
        while(True):
           
            if(not self.Flag):
                pass
            else:
                    display_widgets.canfd_read(self.table_widget1,self.table_widget2,self.ch,self.dbc,self.db,self.select_id)
              
    
    def setFlag(self,parm):                           #外部停止线程的操作函数
        self.Flag=parm                                #boolean

    def set_select_id(self,select_id):   
        self.select_id = select_id
        
    def set_dbc(self,dbc):
        self.dbc = dbc

    def set_db(self,db):
        self.db = db     

class Ui_MainWindow(object):
    def __init__(self):
       
        self.start_flag = 0
        
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(747, 634)
        self.centralWidget = QtWidgets.QWidget(MainWindow)
        self.centralWidget.setObjectName("centralWidget")
        self.tableWidget = QtWidgets.QTableWidget(self.centralWidget)
        self.tableWidget.setGeometry(QtCore.QRect(40, 10, 630, 341))
        self.tableWidget.setObjectName("tableWidget")
        self.tableWidget.setColumnCount(5)
        self.tableWidget.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(3, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(4, item)
        self.tableWidget_2 = QtWidgets.QTableWidget(self.centralWidget)
        self.tableWidget_2.setGeometry(QtCore.QRect(40, 380, 500, 192))
        self.tableWidget_2.setObjectName("tableWidget_2")
        self.tableWidget_2.setColumnCount(2)
        self.tableWidget_2.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_2.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_2.setHorizontalHeaderItem(1, item)
        MainWindow.setCentralWidget(self.centralWidget)
        self.menuBar = QtWidgets.QMenuBar(MainWindow)
        self.menuBar.setGeometry(QtCore.QRect(0, 0, 747, 23))
        self.menuBar.setObjectName("menuBar")
        self.menu = QtWidgets.QMenu(self.menuBar)
        self.menu.setObjectName("menu")
        self.menu_2 = QtWidgets.QMenu(self.menuBar)
        self.menu_2.setObjectName("menu_2")
        self.menuDBC = QtWidgets.QMenu(self.menuBar)
        self.menuDBC.setObjectName("menuDBC")
        MainWindow.setMenuBar(self.menuBar)
        self.statusBar = QtWidgets.QStatusBar(MainWindow)
        self.statusBar.setObjectName("statusBar")
        MainWindow.setStatusBar(self.statusBar)
        self.actionopen = QtWidgets.QAction(MainWindow)
        self.actionopen.setObjectName("actionopen")
        self.actionclose = QtWidgets.QAction(MainWindow)
        self.actionclose.setObjectName("actionclose")
        self.actionstop = QtWidgets.QAction(MainWindow)
        self.actionstop.setObjectName("actionstop")
        self.actionrx = QtWidgets.QAction(MainWindow)
        self.actionrx.setObjectName("actionrx")
        self.actiontx = QtWidgets.QAction(MainWindow)
        self.actiontx.setObjectName("actiontx")
        self.actiondbcfile = QtWidgets.QAction(MainWindow)
        self.actiondbcfile.setObjectName("actiondbcfile")
        self.menu.addAction(self.actionopen)
        self.menu.addAction(self.actionclose)
        self.menu_2.addAction(self.actionrx)
        self.menu_2.addAction(self.actiontx)
        self.menu_2.addAction(self.actionstop)
        self.menuDBC.addAction(self.actiondbcfile)
        self.menuBar.addAction(self.menu.menuAction())
        self.menuBar.addAction(self.menu_2.menuAction())
        self.menuBar.addAction(self.menuDBC.menuAction())

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "CANFD_TOOL"))
        item = self.tableWidget.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "时间"))
        item = self.tableWidget.horizontalHeaderItem(1)
        item.setText(_translate("MainWindow", "方向"))
        item = self.tableWidget.horizontalHeaderItem(2)
        item.setText(_translate("MainWindow", "ID"))
        item = self.tableWidget.horizontalHeaderItem(3)
        item.setText(_translate("MainWindow", "DLC"))
        item = self.tableWidget.horizontalHeaderItem(4)
        item.setText(_translate("MainWindow", "数据"))
        item = self.tableWidget_2.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "信号"))
        item = self.tableWidget_2.horizontalHeaderItem(1)
        item.setText(_translate("MainWindow", "物理值"))
        self.menu.setTitle(_translate("MainWindow", "设备"))
        self.menu_2.setTitle(_translate("MainWindow", "数据"))
        self.menuDBC.setTitle(_translate("MainWindow", "DBC"))
        self.actionopen.setText(_translate("MainWindow", "打开"))
        self.actionclose.setText(_translate("MainWindow", "关闭"))
        self.actionstop.setText(_translate("MainWindow", "停止"))
        self.actionrx.setText(_translate("MainWindow", "接受"))
        self.actiontx.setText(_translate("MainWindow", "发送"))
        self.actiondbcfile.setText(_translate("MainWindow", "路径"))
        
        
        self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.tableWidget_2.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.tableWidget.verticalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.tableWidget_2.verticalHeader().setSectionResizeMode(QHeaderView.Stretch)
        
        self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.tableWidget_2.setEditTriggers(QAbstractItemView.NoEditTriggers)
        
        
        self.actionopen.triggered.connect(self.open_onclick)
        self.actionclose.triggered.connect(self.close_onclick)
        self.actionrx.triggered.connect(self.rx_onclick)
        self.actionstop.triggered.connect(self.stop_onclick)
        self.actiondbcfile.triggered.connect(self.dbc_onclick)

        self.tableWidget.doubleClicked.connect(self.double_onclick)
        
        self.actionrx.setEnabled(0)
        self.actiontx.setEnabled(0)
        self.actionstop.setEnabled(0)
        self.actionclose.setEnabled(0)
                
        self.t1 = CANThread("table_widget",self.tableWidget,self.tableWidget_2,None,None)
        
        self.t1.daemon = True
        ##self.t2.daemon = True
        
       

    def open_onclick(self):
        self.t1.ch.busOn()
        self.actionrx.setEnabled(1)
        self.actionopen.setEnabled(0)
        self.actionclose.setEnabled(1)
        
    def close_onclick(self):
        self.start_flag = 1
        self.t1.setFlag(False) 
        self.t1.ch.busOff()
        self.actionrx.setEnabled(0)
        self.actionopen.setEnabled(1)
        self.actionclose.setEnabled(0)        


    def rx_onclick(self):
        self.t1.setFlag(True) 
        self.actionrx.setEnabled(0)
        self.actionstop.setEnabled(1)
        if not self.start_flag:
            self.t1.start()

            
            self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
            self.tableWidget.verticalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
            self.tableWidget.horizontalHeader().setStretchLastSection(True)
            self.tableWidget.verticalHeader().setStretchLastSection(True)

            self.tableWidget_2.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
            self.tableWidget_2.horizontalHeader().setStretchLastSection(True)
            self.tableWidget_2.verticalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
            self.tableWidget_2.verticalHeader().setStretchLastSection(True)
            


    def stop_onclick(self):
        self.start_flag = 1
        self.t1.setFlag(False)
        self.actionrx.setEnabled(1)
        self.actionstop.setEnabled(0)
        
    def dbc_onclick(self):
        filename, filetype = QFileDialog.getOpenFileName(self.centralWidget, "选择文件", "./","Dbc File(*.dbc)")
        db = kvadblib.Dbc(filename=filename,protocol=9)
        self.t1.set_db(db)
        self.t1.set_dbc(filename)
     
    def double_onclick(self):
        self.t1.set_select_id(None)
        self.tableWidget_2.clearContents()
        self.tableWidget_2.setRowCount(0)
        for i in self.tableWidget.selectedItems():
            #print(i.row(), i.column(), i.text())
            
            select_id = self.tableWidget.item(i.row(),2).text()
            self.t1.set_select_id(select_id)

            
        


display_widgets.py:

from canlib import canlib, kvadblib
import time, datetime
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
import time
import sys

def canfd_read(table_widget1,table_widget2,ch,dbc,db,select_id):
    
    timeout = 1
    
    frame = ch.read(timeout=int(timeout * 1000))
    ###print("id:", hex(frame.id))
    ###print("data:", bytes(frame.data))
    ###print("dlc:", frame.dlc)
    ###print("flags:", frame.flags)
    canfd_data = []
    for i in range(len(frame.data)):
        canfd_data.append(str(hex(frame.data[i])))
        
    timeStamp = float(frame.timestamp)/1000
    ret_datetime = datetime.datetime.utcfromtimestamp(timeStamp).strftime("%H:%M:%S.%f")
                
    items=table_widget1.findItems(str(hex(frame.id)),QtCore.Qt.MatchExactly)
    if(items):
        item = items[0]
        iRow = item.row()   
        table_widget1.setItem(iRow,0,QTableWidgetItem(str(ret_datetime)))        ### 时间
        table_widget1.setItem(iRow,1,QTableWidgetItem("接受"))                   ### rx/tx
        table_widget1.setItem(iRow,2,QTableWidgetItem(str(hex(frame.id))))       ### ID
        table_widget1.setItem(iRow,3,QTableWidgetItem(str(frame.dlc)))           ### DLC
        table_widget1.setItem(iRow,4,QTableWidgetItem(str(canfd_data)))          ### 数据
        table_widget1.viewport().update()
    else:
        iRow = table_widget1.rowCount()
        table_widget1.setRowCount(iRow + 1)
        table_widget1.setItem(iRow,0,QTableWidgetItem(str(ret_datetime)))        ### 时间
        table_widget1.setItem(iRow,1,QTableWidgetItem("接受"))                   ### rx/tx
        table_widget1.setItem(iRow,2,QTableWidgetItem(str(hex(frame.id))))       ### ID
        table_widget1.setItem(iRow,3,QTableWidgetItem(str(frame.dlc)))           ### DLC
        table_widget1.setItem(iRow,4,QTableWidgetItem(str(canfd_data)))          ### 数据


    if(dbc == None) or (select_id == None) or (db == None) or (frame == None):
        return 

    if str(hex(frame.id)) == select_id:    

        ###db = kvadblib.Dbc(filename=dbc,protocol=9)
        try:
            bmsg = db.interpret(frame)
        except:
            print("<<< No message found for frame with id %s >>>" % frame.id)
            return

        
        for bsig in bmsg:
            items=table_widget2.findItems(str(bsig.name),QtCore.Qt.MatchExactly)
            if(items):
                item = items[0]
                iRow = item.row()
                table_widget2.setItem(iRow,0,QTableWidgetItem(str(bsig.name)))
                table_widget2.setItem(iRow,1,QTableWidgetItem(str(bsig.phys)+str(bsig.unit)))
                table_widget2.viewport().update()

            else:
                iRow = table_widget2.rowCount()
                table_widget2.setRowCount(iRow + 1)
                table_widget2.setItem(iRow,0,QTableWidgetItem(str(bsig.name)))
                table_widget2.setItem(iRow,1,QTableWidgetItem(str(bsig.phys)+str(bsig.unit)))

        ###db.close()


       
            
    

有可能是多个线程之间占用tablewidget导致的,如果单独执行tablewidget2也能成功,说明是资源抢夺问题,但tablewidget2无法运行,那就是这部代码有问题了