PyQt如何在线程之间发送send/recieve信号

PyQt how to send/recieve signals between threads

大家好,感谢您的帮助。

我正在使用 PyQt GUI 读取和写入质量流量控制和热通量计的电压。我正在使用 QThreads 在后台有一个线程 运行 不断更新 GUI 中显示的测量值。我 运行 遇到了后台线程实际更新 GUI 的麻烦,因为它无权访问 GUI 线程的功能。根据我在网上阅读的内容,有一些关于 "moving" on thread into other 但我不确定这是什么意思。有人可以 this/point 向我说明正确的方向吗?

这是我的代码:

from PyQt4 import QtGui, QtCore
import sys
import design4
import piplates.DAQC2plate as DAQC2
import time
import threading

air = 0.0
propane = 0
tolerance = .1
n = 1 #number of air controllers

class App4(QtGui.QMainWindow, design4.Ui_MainWindow):
    def __init__(self, parent =None):

        super(self.__class__, self).__init__()
        self.setupUi(self)
        self.sendFlow.clicked.connect(self.inputClicked)
        self.displayFlow.clicked.connect(self.outputClicked)
        self.hfButton.clicked.connect(self.heatFluxRead)

        self.myThread = Worker()
        self.myThread.start()

    def inputClicked(self):

        air = float(self.AirFlowInput.text())
        propane = self.PropaneFlowInput.text()

        if air <= 160 and air > 0:
            acv = air / 20.0 / n *2 +.05#compute air control voltage for each controller
            DAQC2.setDAC(0,0,acv) #changing voltage signal for channel 0
            DAQC2.setDAC(0,1,acv)
        else:
            DAQC2.setDAC(0,0,0)

        print DAQC2.getDAC(0,1)
        print DAQC2.getDAC(0,0)

    def outputClicked(self):

        airRead = float(DAQC2.getADC(0,0)-.01) * 40 / n #converting 0-4Volts to flow
        self.airFlowMeasured.display(airRead)


        #print DAQC2.getADC(0,0)

        #propRead = float(DAQC2.getADC(0,2)-.01) * 20
        #self.propaneFlowMeasured.display(propRead)


        #print DAQC2.getADC(0,1)

        #palette = self.airFlowMeasured.palette()
        #role = self.airFlowMeasured.backgroundRole()
        #if float(DAQC2.getADC(0,0)) < (air*(1-tolerance):
         #                            palette.setColor(role, QColor('yellow'))
        #else if

    def heatFluxRead(self):

        heatFlux = float(DAQC2.getADC(0,7)) * 5800.0 #converts volts to kW/m^2
        self.hfNumber.display(heatFlux)

        print heatFlux
        print self.getADC2(0,7)

    def getADC2(self,addr,channel):
        DAQC2.VerifyADDR(addr)
        DAQC2.VerifyAINchannel(channel) 
        resp= DAQC2.ppCMD(addr,0x30,channel,0,2)
        value=(256*resp[0]+resp[1])
        if (channel==8):
            value=value*5.0*2.4/65536
        else:
            value=(value*24.0/65536)-12.0
            value=round(value*DAQC2.calScale[addr][channel]+DAQC2.calOffset[addr][channel],5)
        return value


def main():

    app = QtGui.QApplication(sys.argv)
    form = App4()
    form.show()

    app.exec_()




class Update(QtCore.QObject):
    sendUpdate = QtCore.pyqtSignal()

class Worker(QtCore.QThread):

    def __init__(self, parent = None):

        QtCore.QThread.__init__(self, parent)

        self.initSignal()

    def initSignal(self):      

        self.u = Update()
        self.u.sendUpdate.connect(self.outputClicked)       


    def run(self):

        while True:
            self.u.sendUpdate.emit()
            print 1
            time.sleep(.25)



if __name__ == '__main__':
    main()

非常感谢您的帮助!

我认为通过DAQC2.getADC()函数读取不会耗费太多时间,所以没必要使用线程,你要做的是周期性任务,所以最合适的选择是使用QTimer:

class App4(QtGui.QMainWindow, design4.Ui_MainWindow):
    def __init__(self, parent =None):

        super(self.__class__, self).__init__()
        self.setupUi(self)

        self.timer = QtCore.QTimer(self)
        self.timer.timeout.connect(self.outputClicked)
        self.timer.setInterval(250)

        self.sendFlow.clicked.connect(self.inputClicked)
        self.displayFlow.clicked.connect(self.timer.start)
        self.hfButton.clicked.connect(self.heatFluxRead)

    def inputClicked(self):

        air = float(self.AirFlowInput.text())
        propane = self.PropaneFlowInput.text()

        if air <= 160 and air > 0:
            acv = air / 20.0 / n *2 +.05#compute air control voltage for each controller
            DAQC2.setDAC(0,0,acv) #changing voltage signal for channel 0
            DAQC2.setDAC(0,1,acv)
        else:
            DAQC2.setDAC(0,0,0)

        print DAQC2.getDAC(0,1)
        print DAQC2.getDAC(0,0)

    def outputClicked(self):

        airRead = float(DAQC2.getADC(0,0)-.01) * 40 / n #converting 0-4Volts to flow
        self.airFlowMeasured.display(airRead)


        #print DAQC2.getADC(0,0)

        #propRead = float(DAQC2.getADC(0,2)-.01) * 20
        #self.propaneFlowMeasured.display(propRead)


        #print DAQC2.getADC(0,1)

        #palette = self.airFlowMeasured.palette()
        #role = self.airFlowMeasured.backgroundRole()
        #if float(DAQC2.getADC(0,0)) < (air*(1-tolerance):
         #                            palette.setColor(role, QColor('yellow'))
        #else if

    def heatFluxRead(self):

        heatFlux = float(DAQC2.getADC(0,7)) * 5800.0 #converts volts to kW/m^2
        self.hfNumber.display(heatFlux)

        print heatFlux
        print self.getADC2(0,7)

    def getADC2(self,addr,channel):
        DAQC2.VerifyADDR(addr)
        DAQC2.VerifyAINchannel(channel) 
        resp= DAQC2.ppCMD(addr,0x30,channel,0,2)
        value=(256*resp[0]+resp[1])
        if (channel==8):
            value=value*5.0*2.4/65536
        else:
            value=(value*24.0/65536)-12.0
            value=round(value*DAQC2.calScale[addr][channel]+DAQC2.calOffset[addr][channel],5)
        return value