Wxpython Break While 循环
Wxpython Break While Loop
我正在创建一个简单的 GUI,一个带有两个按钮的 frame
,使用 wxpython
的“开始”按钮和“停止”按钮。当您按下 Start 按钮时,程序应该从 1 开始打印数字。当您按下 Stop 按钮时,程序应该停止打印数字并打印 'Done'。我正在使用 while 循环来连续打印数字。停止按钮应该 'break' while 循环,但是它会导致程序冻结。我知道我应该以某种方式使用线程。我的问题是:如何将按钮事件创建为线程?
import wx
import time
class PanelOne(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
sizer = wx.BoxSizer(wx.VERTICAL)
self.btn_start = wx.Button(self, label="Start")
self.btn_start.Bind(wx.EVT_BUTTON, self.Loop)
self.btn_stop = wx.Button(self, label="Stop")
self.btn_stop.Bind(wx.EVT_BUTTON, self.Loop)
sizer.Add(self.btn_start, 0, wx.ALL|wx.EXPAND, 5)
sizer.Add(self.btn_stop, 0, wx.ALL|wx.EXPAND, 5)
self.SetSizer(sizer)
self.condition = True
def Loop(self, event):
count = 0
button = event.GetEventObject()
while self.condition:
labelName = button.GetLabel()
count = count+1
print(count)
time.sleep(1)
if labelName == 'Stop':
print("Done")
break
class FrameOne(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="First Frame")
panel = PanelOne(self)
self.Show()
if __name__ == "__main__":
app = wx.App(False)
frame = FrameOne()
app.MainLoop()
尝试创建一个初始设置为 false 的布尔值
让您的开始按钮调用一个将 bool 设置为 true 的线程,然后根据这个 bool 启动一个 while 循环,在这个循环中有您的计数器和任何其他逻辑。
现在您的计数器在它自己的线程中,可以使用停止按钮将 bool 设置为 false,从而终止 while 循环,然后线程将结束。
这里是 link 解释 python 线程
这是我的解决方案。如果有改进的地方,请告诉我。
import wx
import time
import threading
class PanelOne(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
sizer = wx.BoxSizer(wx.VERTICAL)
self.btn_start = wx.Button(self, label="Start")
self.btn_start.Bind(wx.EVT_BUTTON, self.LoopCond)
#self.condition
self.btn_stop = wx.Button(self, label="Stop")
self.btn_stop.Bind(wx.EVT_BUTTON, self.LoopCond)
sizer.Add(self.btn_start, 0, wx.ALL|wx.EXPAND, 5)
sizer.Add(self.btn_stop, 0, wx.ALL|wx.EXPAND, 5)
self.SetSizer(sizer)
def LoopCond(self, event):
button = event.GetEventObject()
self.labelName = button.GetLabel()
if self.labelName == 'Start':
self.condition = True
threading.Thread(target= self.Loop, args=(self.condition,), daemon=True).start()
self.btn_start.Enable(False)
else:
self.condition = False
threading.Thread(target= self.Loop, args=(self.condition,), daemon=True).start()
self.btn_start.Enable(True)
#parent_frame = self.GetParent()
#parent_frame.Close()
def Loop(self, condition):
count = 0
while condition:
count = count+1
print(count)
time.sleep(1)
if self.labelName == 'Stop':
print("Done")
break
class FrameOne(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="First Frame")
panel = PanelOne(self)
self.Show()
if __name__ == "__main__":
app = wx.App(False)
frame = FrameOne()
app.MainLoop()
我正在创建一个简单的 GUI,一个带有两个按钮的 frame
,使用 wxpython
的“开始”按钮和“停止”按钮。当您按下 Start 按钮时,程序应该从 1 开始打印数字。当您按下 Stop 按钮时,程序应该停止打印数字并打印 'Done'。我正在使用 while 循环来连续打印数字。停止按钮应该 'break' while 循环,但是它会导致程序冻结。我知道我应该以某种方式使用线程。我的问题是:如何将按钮事件创建为线程?
import wx
import time
class PanelOne(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
sizer = wx.BoxSizer(wx.VERTICAL)
self.btn_start = wx.Button(self, label="Start")
self.btn_start.Bind(wx.EVT_BUTTON, self.Loop)
self.btn_stop = wx.Button(self, label="Stop")
self.btn_stop.Bind(wx.EVT_BUTTON, self.Loop)
sizer.Add(self.btn_start, 0, wx.ALL|wx.EXPAND, 5)
sizer.Add(self.btn_stop, 0, wx.ALL|wx.EXPAND, 5)
self.SetSizer(sizer)
self.condition = True
def Loop(self, event):
count = 0
button = event.GetEventObject()
while self.condition:
labelName = button.GetLabel()
count = count+1
print(count)
time.sleep(1)
if labelName == 'Stop':
print("Done")
break
class FrameOne(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="First Frame")
panel = PanelOne(self)
self.Show()
if __name__ == "__main__":
app = wx.App(False)
frame = FrameOne()
app.MainLoop()
尝试创建一个初始设置为 false 的布尔值
让您的开始按钮调用一个将 bool 设置为 true 的线程,然后根据这个 bool 启动一个 while 循环,在这个循环中有您的计数器和任何其他逻辑。
现在您的计数器在它自己的线程中,可以使用停止按钮将 bool 设置为 false,从而终止 while 循环,然后线程将结束。
这里是 link 解释 python 线程
这是我的解决方案。如果有改进的地方,请告诉我。
import wx
import time
import threading
class PanelOne(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
sizer = wx.BoxSizer(wx.VERTICAL)
self.btn_start = wx.Button(self, label="Start")
self.btn_start.Bind(wx.EVT_BUTTON, self.LoopCond)
#self.condition
self.btn_stop = wx.Button(self, label="Stop")
self.btn_stop.Bind(wx.EVT_BUTTON, self.LoopCond)
sizer.Add(self.btn_start, 0, wx.ALL|wx.EXPAND, 5)
sizer.Add(self.btn_stop, 0, wx.ALL|wx.EXPAND, 5)
self.SetSizer(sizer)
def LoopCond(self, event):
button = event.GetEventObject()
self.labelName = button.GetLabel()
if self.labelName == 'Start':
self.condition = True
threading.Thread(target= self.Loop, args=(self.condition,), daemon=True).start()
self.btn_start.Enable(False)
else:
self.condition = False
threading.Thread(target= self.Loop, args=(self.condition,), daemon=True).start()
self.btn_start.Enable(True)
#parent_frame = self.GetParent()
#parent_frame.Close()
def Loop(self, condition):
count = 0
while condition:
count = count+1
print(count)
time.sleep(1)
if self.labelName == 'Stop':
print("Done")
break
class FrameOne(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="First Frame")
panel = PanelOne(self)
self.Show()
if __name__ == "__main__":
app = wx.App(False)
frame = FrameOne()
app.MainLoop()