PyQt线程中的Python文件操作处理

时间:2015-04-24 14:48:40

标签: python multithreading file-io serial-port pyqt

我正在考虑打开和读取其数据需要在线程中使用的文件的正确方法。它是一个基于GUI的应用程序,用于读取和写入线程中的串行端口。这现在完美无缺。

在阅读之间,我还想从文件中读取并在特定时间将其写入端口。到目前为止,启动线程的结构是:

  • 打开端口
  • run method

在运行循环中:

  • 阅读时间
  • 从文件中读取
  • 写入端口
  • 如果缓冲区中存在某些内容,请将其读取

最后,如果按钮停止:

  • 关闭端口
  • 终止帖子

现在问题是我不确定如何构建和实现此文件处理。我应该使用我需要的方法为文件处理程序创建一个单独的类,还是只是打开文件并在线程的run()循环中读取它?如果是这样,在我看来它不是Pythonic或OOP,我真的想以正确的方式对其进行编码以便以后能够维护它。

我附加了一段相当简化的代码,以便更好地理解。我删除了一些不重要的东西,但可能还剩下一些东西。非常欢迎你批评它,因为我还是初学者。

class COMThread(QtCore.QThread):
    def __init__(self, parent, *args, **kwargs):
        QtCore.QThread.__init__(self, parent)
        self.myInit (*args, **kwargs)
        self._stop = False              # flag to stop thread
        self.parent = parent

        try:
            self.baudrate = int(self.baud)
            self.port = str(self.port)

            self.ser = serial.Serial(self.port, self.baudrate, timeout=0, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, xonxoff=False, rtscts=False, dsrdtr=False)
        except serial.SerialException:
            logger.error('Cannot open port', exc_info=True)
            self._stop = True
        else:
            self.parent.comPortLabel.setText(u'Connected to port ' + str(self.port))
            self.parent.comConnectButton.setText("Disconnect")

            logger.info('Com Connected to port '+ str(self.port))

            self.connect(self.parent.comPollButton, QtCore.SIGNAL("clicked()"), self.toggleComCustomLine)
            self.connect(self.parent.comFreqSetButton, QtCore.SIGNAL("clicked()"), self.toggleComPollFreq)
            self.connect(self.parent.comCustomCheckBox, QtCore.SIGNAL("stateChanged(int)"), self.toggleComCustomCheck)

            self.connect(self, QtCore.SIGNAL('comSpeed(int)'), self.comWSlcd, QtCore.SLOT('display(int)'))
            self.connect(self, QtCore.SIGNAL('comAngle(int)'), self.comWAlcd, QtCore.SLOT('display(int)'))

    def myInit(self, port, baud):
        self.port = port
        self.baud = baud

    def run (self):                     # class which is automatically called after __init__
        self.txQueue = collections.deque(maxlen=10)

        self.readyToSend = True

        self.messageData = ''
        self.txData = ''

        self.newData = ''

        self.time_start = 0
        self.time_delta_s = 0
        self.time_delta_ms = 0

        self.speed = 0
        self.angle = 0

        self.poll_msg = collections.deque()
        self.poll_msg_t = collections.deque()

        # ------------------  THREAD STARTED ---------------------------------
        logger.info('COM port com thread started...')
        self.time_start = time.time() # initial time
        while self._stop == False:

            self.time_delta_ms, self.time_delta_s = math.modf(time.time() -  self.time_start)
            self.time_delta_ms = int(self.time_delta_ms*1000)

            # prepare data based on timing

            # READ FILE

            # put data to queue
            self.txQueue.append(self.messageData)
            self.poll_msg.rotate(-1)
            self.poll_msg_t.rotate(-1)
            self.response_time_start = time.time()

            # flush out queue and send everything
            if self.readyToSend and len(self.txQueue):
                while len(self.txQueue):
                    self.txData = self.txQueue.popleft()
                    try:
                        n = self.ser.write(self.txData)
                        self.ser.flush()
                    except serial.SerialException:
                        logger.error("Com Could not write to serial port")

            #-------------------------------------------

            time.sleep(0.001)
            n = self.ser.inWaiting()            # check if something in serial buffer

            if n:
                self.readyToSend = False
                try:
                    self.newData = self.newData + self.ser.read(n)
                    logger.debug("S: "+str(self.time_delta_s)+ " ms: "+ str(self.time_delta_ms))
                except serial.SerialException:
                    logger.error('Com Worker cannot read Serial Port !!!')
                else:
                    n = 0
                    # Process received data
            else:
                self.readyToSend = True

        self.ser.close()

        logger.info('Com COM port thread stopped...jump out of loop')
        self.parent.comConnectButton.setText("Connect")
        self.parent.comPortLabel.setText("Disconnected")

    def toggleStop(self):
        self._stop = True
        logger.info("Com Data worker stopped by button")

0 个答案:

没有答案