#!/opt/homebrew/bin/python3 # -*- coding:utf-8 -*- from PyQt6.QtCore import QObject, QTimer, pyqtSignal,QDateTime from logs import log class CommandExec(QObject): def __init__(self, cmd, interval): self.cmd = cmd self.interval = interval class CommandQueue(QObject): runProcessOver = pyqtSignal() runProcessChange = pyqtSignal(int, int, int, int, str) #当前指令序号,总指令个数,当前循环次数,总循环次数,当前指令名称 def __init__(self, name='', loop = 1, delay = 1000): super().__init__() self.reset() self.busyFlag = False #指令正在执行,则Flag为True self.timer = QTimer() self.loopStartTime = QDateTime.currentMSecsSinceEpoch() self.timer.setSingleShot(True) self.timer.timeout.connect(self.__timerHandler) self.setData(name, loop, delay) def setData(self, name='', loop = 1, delay = 1000): self.name = name self.loopCount = loop self.delay = delay def append(self, cmd, cmdInterval = 100, repeat = 1): if repeat < 1: repeat = 1 if cmdInterval < 10: cmdInterval = 10 for _ in range(repeat): cmdEx = CommandExec(cmd, cmdInterval) self.cmdList.append(cmdEx) def reset(self): self.cmdList = list() self.cmdIndex = 0 self.loopIndex = 0 self.running = False self.busyFlag = False #指令正在执行,则Flag为True def stop(self): try: self.timer.stop() if self.busyFlag == True: cmdEx = self.cmdList[self.cmdIndex] cmdEx.cmd.runOver.disconnect(self.__cmdExecOverHandler) cmdEx.cmd.quit() cmdEx.cmd.requestInterruption() cmdEx.cmd.wait() log.info('command queue stop') except Exception as e: if "'method' object is not connected" in str(e): return e log.error(e) finally: self.running = False self.busyFlag = False #指令正在执行,则Flag为True def start(self): if self.running: log.warning("cmd is already running") return self.running = True log.debug('len(self.cmdList)', len(self.cmdList)) self.loopIndex = 0 self.cmdIndex = 0 if len(self.cmdList) == 0: return self.timer.start(10) def __cmdExecOverHandler(self): cmdEx = self.cmdList[self.cmdIndex] log.debug('cmdIndex : ', self.cmdIndex) cmdEx.cmd.runOver.disconnect(self.__cmdExecOverHandler) self.busyFlag = False self.cmdIndex += 1 log.debug('exec over') def __timerHandler(self): if self.busyFlag == True: self.timer.start(10) #当前指令未执行完,延时10ms等待 return if self.cmdIndex >= len(self.cmdList): self.runProcessOver.emit() self.loopIndex += 1 if self.loopIndex < self.loopCount: self.cmdIndex = 0 ts = QDateTime.currentMSecsSinceEpoch() ts = ts - self.loopStartTime if self.delay > ts: self.timer.start(self.delay - ts) return else: self.running = False #队列执行完 return self.busyFlag = True cmdEx = self.cmdList[self.cmdIndex] if self.cmdIndex == 0: self.loopStartTime = QDateTime.currentMSecsSinceEpoch() self.timer.start(cmdEx.interval) log.debug('exec cmd index ', self.cmdIndex, ':', cmdEx.cmd.cmdInfo['name']) cmdEx.cmd.runOver.connect(self.__cmdExecOverHandler) cmdEx.cmd.start() self.runProcessChange.emit( self.cmdIndex, len(self.cmdList), self.loopIndex, self.loopCount, cmdEx.cmd.cmdInfo['name'] )