【发布时间】:2020-08-06 06:51:06
【问题描述】:
我正在制作一个与测量设备通信的数据采集程序。需要定期检查设备的状态(例如,每 0.1 秒)以查看是否已完成采集。此外,该程序必须具有“中止”方法,因为采集有时需要超过几分钟的时间。因此我需要使用多线程。
我附上了流程图和示例代码。但是我不知道如何调用主线程来执行子线程中的方法。
python 3.7.2 wxpython 4.0.6
import wx
import time
from threading import Thread
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="Test Frame")
panel = wx.Panel(self)
self.Btn1 = wx.Button(panel, label="Start Measurement")
self.Btn1.Bind(wx.EVT_BUTTON, self.OnStart)
self.Btn2 = wx.Button(panel, label="Abort Measurement")
self.Btn2.Bind(wx.EVT_BUTTON, self.OnAbort)
self.Btn2.Enable(False)
self.DoneFlag = False
self.SubThread = Thread(target=self.Check, daemon=True)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.Btn1, 0, wx.EXPAND)
sizer.Add(self.Btn2, 0, wx.EXPAND)
panel.SetSizer(sizer)
def OnStart(self, event):
# self.N is the number of data points
self.N = 0
# self.N_max is the number of data points that is going to be acquired
self.N_max = int(input("How many data points do yo want? (greater than 1) : "))
self.DoneFlag = False
self.Btn1.Enable(False)
self.Btn2.Enable(True)
self.Start()
def OnAbort(self, event):
self.DoneFlag = True
def Start(self):
self.SubThread.start()
def Done(self):
if self.DoneFlag is True:
self.Finish()
elif self.DoneFlag is False:
self.Start()
def Finish(self):
print("Measurement done (N = {})\n".format(self.N))
self.Btn1.Enable(True)
self.Btn2.Enable(False)
def Check(self):
# In the actual program, this method communicates with a data acquisition device to check its status
# For example,
# "RunningStatus" is True when the device is still running (acquisition has not been done yet),
# is False when the device is in idle state (acquisition has done)
#
# [Structure of the actual program]
# while True:
# RunningStatus = GetStatusFromDevice()
# if RunningStatus is False or self.DoneFlag is True:
# break
# else:
# time.sleep(0.1)
# In below code, it just waits 3 seconds then assumes the acqusition is done
t = time.time()
time.sleep(1)
for i in range(3):
if self.DoneFlag is True:
break
print("{} sec left".format(int(5-time.time()+t)))
time.sleep(1)
# Proceed to the next steps after the acquisition is done.
if self.DoneFlag is False:
self.N += 1
print("Data acquired (N = {})\n".format(self.N))
if self.N == self.N_max:
self.DoneFlag = True
self.Done() # This method should be excuted in the main thread
if __name__ == "__main__":
app = wx.App()
frame = TestFrame()
frame.Show()
app.MainLoop()
【问题讨论】:
标签: python multithreading wxpython