GUI冻结了工人的睡眠[重复]

问题描述 投票:0回答:1

我创建了一个大项目,涉及通过串行端口与控制器进行通信。我的项目分为3个文件:

文件A-pyqt5设计器文件-包括我的所有按钮,行编辑等。

文件B-串行通信文件-基本上问问题并从控制器接收答案。

文件C-主文件;在此文件中,我正在导入文件A和文件B并使用它们。

在文件C中,我创建了一个工作程序,因此与控制器的所有通信均由该线程进行。 (使用文件B的类和功能。)

现在,我正在尝试在worker中创建一个新函数。该功能每x秒使用time.sleep y次。据我了解,因为我正在使用线程,所以GUI应该不会卡住,但是由于某种原因,它确实会卡住。

由于代码很长,我只附加了我认为与问题相关的内容。我试图复制尽可能少的代码,但仍然使其易于理解,希望可以。

文件A-pyqt5设计器代码:

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):

################creating general veriables#####################
        MainWindow.setObjectName("MainWindow")
        MainWindow.setFixedSize(780, 585)
        font = QtGui.QFont()
        font.setBold(False)
        font.setWeight(50)
        MainWindow.setFont(font)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.frame_Holder = QtWidgets.QFrame(self.centralwidget)
        self.frame_Holder.setGeometry(QtCore.QRect(0, 85, 780, 500))
        self.frame_Holder.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame_Holder.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame_Holder.setObjectName("frame_Holder")


#########################################################################        
################creating veriables for the Top Frame#####################

        self.frame_Top = QtWidgets.QFrame(self.centralwidget)
        self.frame_Top.setEnabled(True)
        self.frame_Top.setGeometry(QtCore.QRect(10, 5, 760, 80))
        font = QtGui.QFont()
        font.setStrikeOut(False)
        self.frame_Top.setFont(font)
        self.frame_Top.setFrameShape(QtWidgets.QFrame.WinPanel)
        self.frame_Top.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame_Top.setLineWidth(1)
        self.frame_Top.setObjectName("frame_Top")        

################creating Buttons#####################

        self.btn_Connect = QtWidgets.QPushButton(self.frame_Top)
        self.btn_Connect.setGeometry(QtCore.QRect(85, 50, 75, 23))
        self.btn_Connect.setObjectName("btn_Connect")
        self.btn_Connect.setEnabled(False)

        self.btn_PortList = QtWidgets.QPushButton(self.frame_Top)
        self.btn_PortList.setGeometry(QtCore.QRect(10, 50, 65, 23))
        self.btn_PortList.setObjectName("btn_PortList")
        self.productMenu=QtWidgets.QMenu(self.frame_Top)
        self.btn_PortList.setMenu(self.productMenu) 
        self.btn_Init = QtWidgets.QPushButton(self.frame_Top)
        self.btn_Init.setEnabled(False)
        self.btn_Init.setGeometry(QtCore.QRect(300, 50, 75, 23))
        self.btn_Init.setObjectName("btn_Init")

################creating text edits#####################
        self.edit_version = QtWidgets.QLineEdit(self.frame_Top)
        self.edit_version.setGeometry(QtCore.QRect(170, 50, 120, 23))
        self.edit_version.setObjectName("edit_version")
        self.edit_version.setEnabled(False)
################creating labels#####################

        self.lbl_Version = QtWidgets.QLabel(self.frame_Top)
        self.lbl_Version.setGeometry(QtCore.QRect(170, 30, 71, 21))
        font = QtGui.QFont()
        font.setPointSize(10)
        font.setBold(True)
        font.setWeight(75)
        self.lbl_Version.setFont(font)
        self.lbl_Version.setObjectName("lbl_Version")             

        self.lbl_FrameTop = QtWidgets.QLabel(self.frame_Top)
        self.lbl_FrameTop.setEnabled(True)
        self.lbl_FrameTop.setGeometry(QtCore.QRect(5, 5, 90, 25))
        font = QtGui.QFont()
        font.setPointSize(12)
        font.setBold(True)
        font.setItalic(True)
        font.setWeight(75)
        font.setStrikeOut(False)
        font.setKerning(True)       
        self.lbl_FrameTop.setFont(font)
        self.lbl_FrameTop.setObjectName("lbl_FrameTop")

        self.lbl_On = QtWidgets.QLabel(self.frame_Top)
        self.lbl_On.setGeometry(QtCore.QRect(528, 30, 41, 16))
        self.lbl_On.setObjectName("lbl_On")

        self.lbl_Enable = QtWidgets.QLabel(self.frame_Top)
        self.lbl_Enable.setGeometry(QtCore.QRect(560, 30, 41, 16))
        self.lbl_Enable.setObjectName("lbl_Enable")

        self.lbl_Rls = QtWidgets.QLabel(self.frame_Top)
        self.lbl_Rls.setGeometry(QtCore.QRect(608, 30, 41, 16))
        self.lbl_Rls.setObjectName("lbl_Rls")

        self.lbl_Chk = QtWidgets.QLabel(self.frame_Top)
        self.lbl_Chk.setGeometry(QtCore.QRect(645, 30, 41, 16))
        self.lbl_Chk.setObjectName("lbl_Chk")

        self.lbl_Wafer = QtWidgets.QLabel(self.frame_Top)
        self.lbl_Wafer.setGeometry(QtCore.QRect(683, 30, 41, 16))
        self.lbl_Wafer.setObjectName("lbl_Wafer")

        self.lbl_Err = QtWidgets.QLabel(self.frame_Top)
        self.lbl_Err.setGeometry(QtCore.QRect(725, 30, 20, 16))
        self.lbl_Err.setObjectName("lbl_Err")

        self.lbl_Port = QtWidgets.QLabel(self.frame_Top)
        self.lbl_Port.setGeometry(QtCore.QRect(10, 30, 51, 21))
        font = QtGui.QFont()
        font.setPointSize(10)
        font.setBold(True)
        font.setItalic(True)
        font.setWeight(75)
        self.lbl_Port.setFont(font)
        self.lbl_Port.setObjectName("lbl_Port")              



#########################################################################        


        self.frame_AutoRun = QtWidgets.QFrame(self.frame_Holder)
        self.frame_AutoRun.setEnabled(False)
        self.frame_AutoRun.setGeometry(QtCore.QRect(10, 90, 760, 320))
        font = QtGui.QFont()
        self.frame_AutoRun.setFont(font)
        self.frame_AutoRun.setFrameShape(QtWidgets.QFrame.WinPanel)
        self.frame_AutoRun.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame_AutoRun.setLineWidth(1)
        self.frame_AutoRun.setObjectName("frame_AutoRun")

        self.lbl_AutoRun = QtWidgets.QLabel(self.frame_AutoRun)
        self.lbl_AutoRun.setGeometry(QtCore.QRect(5, 5, 110, 25))
        font = QtGui.QFont()
        font.setPointSize(12)
        font.setBold(True)
        font.setItalic(True)
        font.setWeight(75)
        font.setStrikeOut(False)
        font.setKerning(True)
        self.lbl_AutoRun.setFont(font)
        self.lbl_AutoRun.setObjectName("lbl_AutoRun")

        self.btn_RunStop = QtWidgets.QPushButton(self.frame_AutoRun)
        self.btn_RunStop.setGeometry(QtCore.QRect(500, 40, 60, 23))
        font = QtGui.QFont()
        font.setPointSize(8)
        font.setBold(False)
        font.setWeight(50)
        font.setKerning(True)
        self.btn_RunStop.setFont(font)
        self.btn_RunStop.setObjectName("btn_RunStop")



        ########################4##########################



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





    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "ECC GUI"))
        self.btn_Connect.setText(_translate("MainWindow", "Connect"))
        self.btn_PortList.setText(_translate("MainWindow", "Ports"))
        self.lbl_Version.setText(_translate("MainWindow", "Version"))
        self.btn_Init.setText(_translate("MainWindow", "Initiate"))
        self.lbl_FrameTop.setText(_translate("MainWindow", "Connect"))##########
        self.lbl_Port.setText(_translate("MainWindow", "Ports"))
        self.lbl_On.setText(_translate("MainWindow", "ON"))
        self.lbl_Enable.setText(_translate("MainWindow", "Enable"))
        self.lbl_Rls.setText(_translate("MainWindow", "RLS"))
        self.lbl_Chk.setText(_translate("MainWindow", "CHK"))
        self.lbl_Wafer.setText(_translate("MainWindow", "Wafer"))
        self.lbl_Err.setText(_translate("MainWindow", "ERR"))
        self.lbl_AutoRun.setText(_translate("MainWindow", "Auto Run"))
        self.btn_RunStop.setText(_translate("MainWindow", "Run"))

文件B-串行通信文件

import serial 
from string import hexdigits
from re import search
class ECC():
    def __init__(self,Port ):
        self.ser = serial.Serial(port ='COM'+str(Port), baudrate= 38400,timeout=1)
    def cmd(self,command):
        return ('00'+command+chr(13)).encode('utf-8')

    def disconnect(self):
        self.ser.close()

    def init(self):
        self.ser.write(self.cmd('INI'))
        return(self.ser.readline().decode('utf-8')[:3])        

    def spr(self,address,value):
        self.ser.write(self.cmd('SPR'+str(address)+str(value)))
        return (self.ser.readline().decode('utf-8')[:3])


    def rpr(self,address):
        self.ser.write(self.cmd('RPR'+str(address)))
        return(self.ser.readline().decode('utf-8')[3:7])


    def chuck(self):
        self.ser.write(self.cmd('CHK'))
        return(self.ser.readline().decode('utf-8')[:3])        

    def rls(self):
        self.ser.write(self.cmd('RLS'))
        return(self.ser.readline().decode('utf-8')[:3])          

    def cap(self):
        self.ser.write(self.cmd('cap'))
        cap=self.ser.readline()[3:].decode('utf-8')
        cap=cap.rstrip()
        if (all(c in hexdigits for c in cap) and cap!=""):
            return int(cap,16)
        else:
            return("Busy...")

    def version(self):
        self.ser.write(self.cmd('VER'))
        return(self.ser.readline().decode('utf-8')[:9])

    def gst(self):
        self.ser.flushInput()
        self.ser.flushOutput()
        self.ser.write(self.cmd('GST'))
        gst=self.ser.readline()
        gst=gst.decode('utf-8')
        is_STV=search('^STV',str(gst))
        if (is_STV):
            stat_hex=gst[3:]
            stat_bin=(bin(int(stat_hex,16))[2:].zfill(16))
            stat_bool=[bool(int(bit)) for bit in stat_bin] 
        else:
            stat_hex="ERR"
            stat_bool="ERR"

        return stat_hex, stat_bool

    def statLights(self):
        [stat_hex, stat_bool]=self.gst()
        if(not stat_hex=="ERR"):
            lights=[not(stat_bool[3]),not(stat_bool[5]),not(stat_bool[10]),stat_bool[10],stat_bool[11],stat_bool[0]]
        else:
            lights="ERR"
        return lights




    def msrphys(self):
        self.ser.flushInput()
        self.ser.flushOutput()
        self.ser.write(self.cmd('msr'))
        A=list()
        A.append(self.ser.readline())
        A[0]=A[0][3:7]
        exists=search('[0-9A-Fa-f]{4}',str(A[0]))

        if(exists):
            A[0]=int(A[0],16)*-0.08398628+2500
            for ind in range(1,32):

                A.append(self.ser.readline())
                exists=search('[0-9A-Fa-f]{4}',str(A[ind]))
                if (exists):
                    A[ind]=int(A[ind].decode('utf-8'),16)*-0.08398628+2500
                else:
                    A[0]="ERR"
                    break
            self.ser.readline()

            A[12]=A[12]*5.75
            A[13]=A[13]*5.75
            A[14]=A[14]*0.1
        else:
            A[0]="ERR"
        return A

文件C-执行文件

from test_des import Ui_MainWindow
from PyQt5 import QtWidgets, QtCore, QtGui
from test_serialCom import ECC
import serial.tools.list_ports
import sys
from re import findall
import time
from functools import partial
try:
    import queue
except ImportError:
    import Queue as queue

class eccWorker(QtCore.QRunnable):
    def __init__(self,port,q):
        super(eccWorker, self).__init__()
        self.finished = QtCore.pyqtSignal() 
        self.port=port
        self.Q=q
        self.threadactive=True
    def run(self):
        if(self.threadactive==True):
            try:
                self.ecc=ECC(self.port)
            except:
                self.threadactive=False
                self.Q.put("ERROR-Not connected")
                self.Q.put("ERROR-Not connected")
            else:
                self.Q.put(self.ecc.version())
                self.Q.put(self.ecc.rpr('04'))
    def init(self):
        if(self.threadactive):
            self.ecc.init()  

    def disconnect(self):
        self.ecc.disconnect()
        self.threadactive=False

    def readCap(self):
        if(self.threadactive==True):
            self.Q.put(self.ecc.cap())

    def chk(self):
        if(self.threadactive==True):
            self.ecc.chuck()

    def rls(self):
        if(self.threadactive==True):
            self.ecc.rls()

    def rprWorker(self,par):
        if(self.threadactive==True):
            self.Q.put(self.ecc.rpr(par))

    def sprWorker(self,par,val):
        if(self.threadactive==True):
#            par=par.zfill(2)
            isOk=self.ecc.spr(par,val)
            if (isOk!="NAK"):
                self.Q.put(self.ecc.rpr(par))

    def getStat(self):
        if(self.threadactive==True):
            statLight=self.ecc.statLights()
            if(statLight=="ERR"):
                self.Q.put("ERR")
            else:
                for i in statLight:
                    self.Q.put(i)

    def sprWorkerNoRpr(self,par,val):
        if(self.threadactive==True):
            isOk=self.ecc.spr(par,val)
            if (isOk!="NAK"):
                return True

    def test1(self,Vchk,N,dt,Dt,threshold):
        Vchk=str(Vchk).zfill(4)
        if(self.sprWorkerNoRpr('04',Vchk)):
            cap1=list()
            cap2=list()
            for i in range(N):
                self.rls()
                time.sleep(dt)
                self.readCap()
                res=self.Q.get()
                if (res!="Busy..."):
                    cap1.append(int(str(res)))
                time.sleep(Dt)
                self.chk()
                time.sleep(dt)
                self.readCap()
                res2=self.Q.get()
                if (res2!="Busy..."):
                    cap2.append(int(str(res2)))
                time.sleep(Dt)
            self.rls()
            cap_Rls=sum(cap1)/len(cap1)     
            cap_Chk=sum(cap2)/len(cap2)
            if((max(cap2)-min(cap1))>threshold):
               isPass=True
            else:
                isPass=False
            self.Q.put(cap_Rls)
            self.Q.put(cap_Chk)
            self.Q.put(isPass)
            print("Done!")


class ApplicationWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(ApplicationWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.threadpool=QtCore.QThreadPool()        
        self.Q=queue.Queue()


        self.ui.productMenu.aboutToShow.connect(self.findPort)
        self.ui.btn_Connect.clicked.connect(self.connectClicked)        
        self.ui.btn_RunStop.clicked.connect(self.run)
        self.ui.btn_Init.clicked.connect(self.initClicked)

        self.redOff=QtGui.QColor(120,0,0)
        self.redOn=QtGui.QColor(255,0,0)
        self.grnOff=QtGui.QColor(7,100,0)
        self.grnOn=QtGui.QColor(16,243,0)
        self.yelOff=QtGui.QColor(155,80,0)
        self.yelOn=QtGui.QColor(255,127,0)

        self.onPen=QtGui.QPen(self.grnOff, 8, QtCore.Qt.SolidLine)
        self.enablePen=QtGui.QPen(self.grnOff, 8, QtCore.Qt.SolidLine)
        self.rlsPen=QtGui.QPen(self.grnOff, 8, QtCore.Qt.SolidLine)
        self.chkPen=QtGui.QPen(self.grnOff, 8, QtCore.Qt.SolidLine)
        self.waferPen=QtGui.QPen(self.yelOff, 8, QtCore.Qt.SolidLine)
        self.errPen=QtGui.QPen(self.redOff, 8, QtCore.Qt.SolidLine)

    def paintEvent(self, e):

       onLedPainter = QtGui.QPainter(self)
       onLedPainter.setPen(self.onPen)
       onLedPainter.setBrush(self.grnOff)
       onLedPainter.drawEllipse(540,55,10,10)

       enabledLedPainter = QtGui.QPainter(self)
       enabledLedPainter.setPen(self.enablePen)
       enabledLedPainter.setBrush(self.grnOff)
       enabledLedPainter.drawEllipse(580,55,10,10)

       rlsLedPainter = QtGui.QPainter(self)
       rlsLedPainter.setPen(self.rlsPen)
       rlsLedPainter.setBrush(self.grnOff)
       rlsLedPainter.drawEllipse(620,55,10,10)

       chkLedPainter = QtGui.QPainter(self)
       chkLedPainter.setPen(self.chkPen)
       chkLedPainter.setBrush(self.grnOff)
       chkLedPainter.drawEllipse(660,55,10,10)

       waferLedPainter = QtGui.QPainter(self)
       waferLedPainter.setPen(self.waferPen)
       waferLedPainter.setBrush(self.yelOff)
       waferLedPainter.drawEllipse(700,55,10,10)

       errLedPainter = QtGui.QPainter(self)
       errLedPainter.setPen(self.errPen)
       errLedPainter.setBrush(self.redOff)
       errLedPainter.drawEllipse(740,55,10,10)


    def updateStat(self):
        #####updating LEDs####
            self.worker.getStat()
            self.ledStat=list()
            self.ledStat.append(self.worker.Q.get())
            if(not self.ledStat[0]=="ERR"):
                for i in range(5):
                    self.ledStat.append(self.worker.Q.get())
                if(self.ledStat[0]):
                    self.onPen=QtGui.QPen(self.grnOn, 8, QtCore.Qt.SolidLine)
                else:
                    self.onPen=QtGui.QPen(self.grnOff, 8, QtCore.Qt.SolidLine)

                if(self.ledStat[1]):
                    self.enablePen=QtGui.QPen(self.grnOn, 8, QtCore.Qt.SolidLine)
                else:
                    self.enablePen=QtGui.QPen(self.grnOff, 8, QtCore.Qt.SolidLine) 

                if(self.ledStat[2]):
                    self.rlsPen=QtGui.QPen(self.grnOn, 8, QtCore.Qt.SolidLine)
                    self.chkPen=QtGui.QPen(self.grnOff, 8, QtCore.Qt.SolidLine)
                else:
                    self.chkPen=QtGui.QPen(self.grnOn, 8, QtCore.Qt.SolidLine)
                    self.rlsPen=QtGui.QPen(self.grnOff, 8, QtCore.Qt.SolidLine)

                if(self.ledStat[4]):
                        self.waferPen=QtGui.QPen(self.yelOn, 8, QtCore.Qt.SolidLine)
                else:
                        self.waferPen=QtGui.QPen(self.yelOff, 8, QtCore.Qt.SolidLine) 

                if(self.ledStat[5]):
                    self.errPen=QtGui.QPen(self.redOn, 8, QtCore.Qt.SolidLine)
                else:
                    self.errPen=QtGui.QPen(self.redOff, 8, QtCore.Qt.SolidLine)
                self.update()
            else:                
                self.connectClicked()
                self.ui.edit_version.setText("GST Disconnected!")

    def findPort(self):
           self.ui.productMenu.clear()
           comPorts = list(serial.tools.list_ports.comports())    # get a list of all devices connected through serial port
           comPorts=sorted(comPorts)
           for port in comPorts:
                   self.ui.productMenu.addAction(str(port),self.selectedPort)

    def selectedPort(self):
        self.portNum=self.sender()
        self.portNum=self.portNum.text()
        self.portNum=findall("COM\d+",self.portNum)
        self.ui.btn_PortList.setText(str(self.portNum[0]))
        self.portNum=self.portNum[0][3:]
        self.ui.btn_Connect.setEnabled(True)

    def connectClicked(self):
        if (self.ui.btn_Connect.text()=="Connect"):
            self.worker=eccWorker(self.portNum,self.Q)
            self.threadpool.start(self.worker)
            ver=self.worker.Q.get()
            volHex=self.worker.Q.get()

            if(ver[:3]=="VER"):
                self.ui.btn_Connect.setText("Disconnect")
                self.ui.btn_PortList.setEnabled(False)
                self.ui.edit_version.setText(ver)
                self.ui.btn_Init.setEnabled(True)
                self.ui.frame_AutoRun.setEnabled(True)


                self.timer_updateStat = QtCore.QTimer()
                self.timer_updateStat.setInterval(500)
                self.timer_updateStat.timeout.connect(self.updateStat)
                self.timer_updateStat.start()                


            else:
                self.ui.edit_version.setText("Error!")
        else:        
            self.timer_updateStat.stop()
            self.worker.disconnect()
            self.ui.btn_Connect.setText("Connect")
            self.ui.btn_Connect.setEnabled(False)
            self.ui.btn_Init.setEnabled(False)
            self.ui.frame_AutoRun.setEnabled(False)
            self.ui.btn_PortList.setEnabled(True)
            self.ui.edit_version.clear()
            self.setFixedSize(780,585)
            self.ui.btn_PortList.setText("Ports")
            self.onPen=QtGui.QPen(self.grnOff, 8, QtCore.Qt.SolidLine)
            self.enablePen=QtGui.QPen(self.grnOff, 8, QtCore.Qt.SolidLine) 
            self.chkPen=QtGui.QPen(self.grnOff, 8, QtCore.Qt.SolidLine)
            self.rlsPen=QtGui.QPen(self.grnOff, 8, QtCore.Qt.SolidLine)
            self.waferPen=QtGui.QPen(self.yelOff, 8, QtCore.Qt.SolidLine) 
            self.errPen=QtGui.QPen(self.redOff, 8, QtCore.Qt.SolidLine)
            self.update()

    def initClicked(self):
        self.worker.init()

    def run(self):
        self.worker.test1(200,5,0.2,0.3,100)
        cap_Rls=self.Q.get()
        cap_Chk=self.Q.get()
        ispass=self.Q.get()
        print("cap_Rls:\n")
        print(cap_Rls)
        print("cap_Chk:\n")
        print(cap_Chk)
        print(ispass)


    def closeEvent(self,event):
        try:
            self.worker.disconnect()
        finally:
            sys.exit()

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    application = ApplicationWindow()
    application.show()
    sys.exit(app.exec_())

因此,即使我使用线程,GUI在功能执行期间也会卡住什么?我该怎么做才能解决此问题?

而且,理想情况下,我想拥有另一个文件D,它包含一个名为TESTS的主类,并且其中包含5个函数,每个函数代表一个测试。我面对上述问题,就是无法从文件C中处于活动状态的线程调用/获取信息,因此,如果您对如何使该线程也有所了解,将不胜感激。 (如果不创建另一个文件,请将所有测试存储在不同的类中。在这里,我也遇到了一些问题,无法使其正常工作。)

python multithreading user-interface pyqt5 sleep
1个回答
0
投票

[经过许多小时的在线搜索,我发现使用QtTest.QTest.qWait(msecs)而不是sleep给了我想要的结果-它包含命令,但不会使GUI冻结。为了使用它,我必须使用from PyQt5 import QtTest

[如果有人对以上任何问题有更好的建议,我希望看到它们。

© www.soinside.com 2019 - 2024. All rights reserved.