【问题标题】:Ending A Function In Python在 Python 中结束一个函数
【发布时间】:2013-04-01 04:31:09
【问题描述】:

我在 python 中有一个使用 Tkinter 的循环函数,当我使用 Tkinter 按下一个按钮时,它并没有结束。它继续使用按钮指定的新功能,但也继续使用旧功能

这是代码(部分):

def countdown(self):

        if self.seconds <= 0:
            if self.minutes > 0:
                self.seconds += 59
                self.minutes -= 1
            elif self.minutes == 0:
                if self.hours != 0:
                    self.minutes += 59
                    self.seconds += 59
                    self.hours -= 1
                else:
                    self.timerLab.configure(text="Times Up!")

        self.timerLab.configure(text="Time Remaining: %d:%d:%d " % (self.hours,self.minutes,self.seconds))
        self.seconds -= 1
        self.after(1000, self.countdown)

那么一旦按下另一个按钮,我该如何结束。有什么东西可以结束当前进程吗?

【问题讨论】:

  • 你不能放置一个名为 isRunning 的模块级布尔变量吗?按下开始按钮时设为真,按下停止按钮时设为假。在这个 countdown() 函数中,您必须检查该变量是否为真才能继续..
  • 是的,这可能会解决它

标签: python function python-2.7 tkinter


【解决方案1】:

Tkinter 使用after_cancel() 方法解决了这个问题。您必须存储after 返回的“后标识符”并将其传递给after_cancel

def start_countdown(self):
    if self.after_id is not None:
        self.after_cancel(self.after_id)
    self.countdown()

def countdown(self):
    # ...
    self.after_id = self.after(1000, self.countdown)

【讨论】:

    【解决方案2】:

    如果您可以使用 Ctrl+C 停止它,那么有很多方法可以实现这一点。我不是这方面的专家,但从 Google 的快速搜索来看,类似这样的方法似乎可行:

    import signal 
    import sys
    import subprocess
    
    def signal_handler(signal, frame):
        print 'You pressed Ctrl+C!'
        sys.exit(0)
    

    还有this 解决方案,它在 ESC 上退出(您只需将 27 更改为另一个键的编号即可):

    import msvcrt
    
    while 1:
        print 'Testing..'
        # body of the loop ...
        if msvcrt.kbhit():
        if ord(msvcrt.getch()) == 27:
            break
    

    希望对你有帮助。

    【讨论】:

    • 谢谢,但我试图通过简单地按下应用程序上的按钮而不是键盘来解决问题。如果您误解了,我很抱歉,但老实说,这将在未来的程序中派上用场,所以谢谢 :)
    • 哦!真的很抱歉,完全被误解了。恐怕我无法帮助你,没有任何经验。不过,很高兴听到我的“答案”有些用处。
    【解决方案3】:

    有一个设置变量的按钮。让您的倒计时函数检查该变量,并仅在变量设置为特定值时重新安排自身。

    类似这样的:

    def __init__(self):
        ...
        self.running = False
    
        start_button = Button(..., self.start, ...)
        quit_button = Button(..., self.stop, ...)
    
    def start(self):
        self.running = True;
        self.countdown()
    
    def stop(self):
        self.running = False;
    
    def countdown(self):
        ...
        if (self.running):
            self.after(1000, self.countdown)
    

    【讨论】:

      【解决方案4】:

      有什么东西可以结束当前进程

      停止当前主循环并销毁所有小部件;你可以打电话给root.destroy():

      #!/usr/bin/env python
      import sys
      from Tkinter import Tk, Button
      
      def counter(root, n=0):
          sys.stderr.write("\r%3s" % n)
          root.after(1000, counter, root, n + 1)
      
      root = Tk()
      Button(root, text="Quit", command=root.destroy).pack()
      counter(root)
      root.mainloop()
      

      【讨论】:

      • 代码按照它说的去做;我很感激对否决票的解释。
      • OP问的是如何停止调用after的回调函数,而不是如何退出主循环。如果您不同意否决票,我很抱歉,但 destroy 与预定功能无关。
      • 感谢您的解释。我明白你的意思了。我已经解释了这个问题(它似乎不正确),因为 OP 想要关闭 GUI 因此 root.destroy() 而不是用 .after_cancel() 取消回调链(在这种情况下更合适)。顺便说一句,如果原因很清楚,我不介意投反对票(这是一个有用的反馈)。
      猜你喜欢
      • 2015-08-05
      • 1970-01-01
      • 2015-07-14
      • 1970-01-01
      • 2017-07-08
      • 1970-01-01
      • 1970-01-01
      • 2020-03-15
      • 2022-11-29
      相关资源
      最近更新 更多