我正在考虑打开和读取其数据需要在线程中使用的文件的正确方法。它是一个基于GUI的应用程序,用于读取和写入线程中的串行端口。这现在完美无缺。
在阅读之间,我还想从文件中读取并在特定时间将其写入端口。到目前为止,启动线程的结构是:
在运行循环中:
最后,如果按钮停止:
现在问题是我不确定如何构建和实现此文件处理。我应该使用我需要的方法为文件处理程序创建一个单独的类,还是只是打开文件并在线程的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")