使用 Toggle 按钮停止循环

2024-08-06 09:41:21 浏览数 (3)

1. 问题背景

用户希望使用 wxPython 创建一个带有滑块和按钮的 GUI 界面,当按下按钮时,滑块的值开始增加,当再次按下按钮时,滑块停止增加。但是,用户在循环中使用 time.sleep() 暂停,导致无法在按下按钮后立即停止循环。

2. 解决方案

有两种解决方法:

  • 使用定时器 (timer)

优点:定时器可以更精确地控制循环,并且在不同平台上更具可移植性。

代码示例:

代码语言:javascript复制
import wx
​
class MyPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
​
        self.slider = wx.Slider(self, value=1, minValue=0, maxValue=100, size=(250, -1),
                                style=wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_LABELS)
        self.slider.SetTickFreq(5, 1)
        self.slider.Bind(wx.EVT_SCROLL, self.onScroll)
        self.toggle = wx.ToggleButton(self, label="Start")
        self.toggle.Bind(wx.EVT_TOGGLEBUTTON, self.onToggle)
​
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.onUpdate, self.timer)
​
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.slider, 0, wx.ALL, 5)
        sizer.Add(self.toggle, 0, wx.ALL, 5)
        self.SetSizer(sizer)
​
    def onScroll(self, event):
        value = self.slider.GetValue()
        self.slider_value = value
​
    def onToggle(self, event):
        value = self.toggle.GetValue()
        if value:
            self.toggle.SetLabel("Pause")
            self.timer.Start(1000)
        else:
            self.timer.Stop()
            self.toggle.SetLabel("Start")
​
    def onUpdate(self, event):
        self.slider_value  = 1
        self.slider.SetValue(self.slider_value)
​
class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="Slider Test")
        panel = MyPanel(self)
        self.Show()
​
if __name__ == "__main__":
    app = wx.App(False)
    frame = MyFrame()
    app.MainLoop()
  • 使用 while 循环并不断检查变量值

优点:这种方法更简单,并且在某些情况下可能更有效。

代码示例:

代码语言:javascript复制
import wx
​
class MyPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
​
        self.slider = wx.Slider(self, value=1, minValue=0, maxValue=100, size=(250, -1),
                                style=wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_LABELS)
        self.slider.SetTickFreq(5, 1)
        self.slider.Bind(wx.EVT_SCROLL, self.onScroll)
        self.toggle = wx.ToggleButton(self, label="Start")
        self.toggle.Bind(wx.EVT_TOGGLEBUTTON, self.onToggle)
​
        self.running = False
​
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.slider, 0, wx.ALL, 5)
        sizer.Add(self.toggle, 0, wx.ALL, 5)
        self.SetSizer(sizer)
​
    def onScroll(self, event):
        value = self.slider.GetValue()
        self.slider_value = value
​
    def onToggle(self, event):
        value = self.toggle.GetValue()
        if value:
            self.toggle.SetLabel("Pause")
            self.running = True
        else:
            self.toggle.SetLabel("Start")
            self.running = False
​
    def updateSlider(self):
        while self.running and self.slider_value < 100:
            self.slider_value  = 1
            self.slider.SetValue(self.slider_value)
            time.sleep(0.1)
​
class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="Slider Test")
        panel = MyPanel(self)
        self.Show()
​
if __name__ == "__main__":
    app = wx.App(False)
    frame = MyFrame()
    app.MainLoop()

........

1 人点赞