问题
I have a panel in wxPython where I want to take a button enable monitor and when clicked start a loop of the below, but also free up the GUI again and thusly update the button label to disable monitor. Once disable is clicked, it would stop the loop entirely.
I've looked at threading, but I am not sure that is what I should be doing in this case?
The entire loop runs within a def startStop(self) declaration and is run within the wxPanel's class.
I'm in way over my head, but I've been tinkering with this GUI for a while now and would love to round out this lesson with doing it the right way. :)
Pseudo code:
while zonesToMonitor != []:
time.sleep(int(self.tc_CheckInterval.Value))
j = 0
for i in zonesToMonitor:
maxVOL = maxVolPerZone[j]
urllib.urlopen("http://" + ip_address + ":" + self.tc_serverPort.Value +"/data/rendererData?data=R::" + wx.FindWindowByLabel(i).Label).read()
INFO = urllib.urlopen("http://" + ip_address + ":" + self.tc_serverPort.Value +"/data/rendererAction?data=class").read()
curTime = datetime.datetime.now()
curTime = curTime.strftime("%H:%M")
if self.ck_QuietHours.Value == True:
quietStartHr = self.tc_quietHr.Value
quietEndHr = self.tc_quietHrStop.Value
quietVol = self.tc_QuietVol.Value
if (curTime > quietStartHr) and (curTime < quietEndHr):
print "In quiet hours..."
maxVOL = quietVol
if self.ck_MuteHours.Value == True:
muteStartHr = self.tc_MuteHr.Value
muteEndHr = self.tc_MuteHrStop.Value
if (curTime > muteStartHr) and (curTime < muteEndHr):
print "In mute time..."
maxVOL = 0
OUTPUT = re.findall('(?<=VOLUME::).*?(?=_\|_)', INFO)
if maxVOL == '':
maxVOL = 0
if OUTPUT == '':
OUTPUT = 0
OUTPUT = map(int, OUTPUT)
if OUTPUT > int(maxVOL):
url = "http://" + ip_address + ":" + self.tc_serverPort.Value + "/data/rendererAction?data=VOLUME::" + str(maxVOL)
urllib.urlopen(url).read()
j += 1
回答1:
i don't think its a bad choice at all to implement this kind of task with Threads, you can read more about threads and wxpython here: Non-Blocking Gui, and also here: LongRunningTasks where the author discusses the alternatives to threading with wxpython.
it can be done in the following way:
class MyThread(Thread):
def __init__(self):
Thread.__init__(self)
self.ToKill = False
def run(self):
while True:
self.FooHandler()
if self.ToKill:
return None
def FooHandler(self):
""" your function here """
print 3
class Panel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, id=-1, style=wx.RAISED_BORDER)
Bsizer = wx.BoxSizer(wx.VERTICAL)
button=wx.ToggleButton(self, label="Click To Enable")
Bsizer.Add(button,1,wx.ALL | wx.EXPAND)
self.SetSizer(Bsizer)
self.Bind(wx.EVT_TOGGLEBUTTON,self.buttonEvt,id=button.GetId())
def buttonEvt(self, evt):
clickedToggleButton = evt.GetEventObject()
if clickedToggleButton.GetValue():
self.thread = MyThread()
self.thread.start()
clickedToggleButton.SetLabel("Click To Disable")
else:
self.thread.ToKill = True
clickedToggleButton.SetLabel("Click To Enable")
来源:https://stackoverflow.com/questions/36893515/looping-in-the-gui