【问题标题】:Countdown timer's speed increases as I press start and pause button one after another for few times in tkinter当我在 tkinter 中按下开始和暂停按钮几次时,倒数计时器的速度会增加
【发布时间】:2019-05-23 02:30:23
【问题描述】:

我有一个倒计时脚本,当我一次又一次按下开始和暂停按钮几次时,秒数会快速更新。

起初我认为在开始和暂停按钮之间快速单击会加快秒数,因此我添加了time.sleep(1) 以延迟在不起作用的按钮之间单击。

我该如何解决这个问题?

我的算法正确吗?或者还有其他更好的方法来进行倒计时吗?如果是,我该怎么做?

代码

from tkinter import *

PAUSE = False
HOUR, MINUTE, SECOND = 0, 0, 0


def start():
    '''Command for START button'''

    global PAUSE

    PAUSE = False
    start_button['state'] = 'disabled'
    pause_button['state'] = 'normal'
    reset_button['state'] = 'normal'
    # time.sleep(1) to delay time between clicks of pause and start buttons
    Counter()


def pause():
    '''Command for PAUSE button'''

    global PAUSE

    PAUSE = True
    start_button['state'] = 'normal'
    pause_button['state'] = 'disabled'


def reset():
    '''Command for RESET button'''

    global HOUR, MINUTE, SECOND, PAUSE

    PAUSE = True
    start_button['state'] = 'normal'
    pause_button['state'] = 'disabled'
    reset_button['state'] = 'disabled'
    Time['text'] = '00:00:00'

    HOUR, MINUTE, SECOND = 0, 0, 0


def Counter():
    '''Updating hour, minute and seconds'''

    global HOUR, MINUTE, SECOND

    if PAUSE is False:
        if SECOND == 59:
            if MINUTE == SECOND == 59:
                HOUR += 1

            if MINUTE == 59:
                MINUTE = 0

            else:
                MINUTE += 1

            SECOND = -1

        SECOND += 1

        Time.config(text='{}:{}:{}'.format(str(HOUR).zfill(2), str(MINUTE).zfill(2), str(SECOND).zfill(2)))
        root.after(1000, Counter)


root = Tk()
root.title('COUNTER')

width, height = 342, 108
pos_x = root.winfo_screenwidth() // 2 - width // 2
pos_y = root.winfo_screenheight() // 2 - height // 2

root.geometry('{}x{}+{}+{}'.format(width, height, pos_x, pos_y))

Time = Label(root, fg='Black', text='00:00:00', font=("Helvetica", 40))
Time.pack(side='bottom')

start_button = Button(root, text='START', font=("Arial", 16), fg='black', width=8, command=start)
start_button.pack(side='left')

pause_button = Button(root, text='PAUSE', font=("Arial", 16), fg='black', width=8, state='disabled', command=pause)
pause_button.pack(side='left')

reset_button = Button(root, text='RESET', font=("Arial", 16), fg='black', width=10, state='disabled', command=reset)
reset_button.pack(side='left', fill='both')

root.mainloop()

【问题讨论】:

    标签: python windows tkinter


    【解决方案1】:

    起初我认为在开始和暂停按钮之间快速单击会加快秒数,因此我添加了 time.sleep(1) 以延迟在不起作用的按钮之间单击。

    问题在于,由于.aftert() 方法回调自身之前存在延迟,因此多次点击开始按钮并创建.after(1000, counter) 的多个循环。这意味着有许多.after() 循环同时发生。要解决这个问题,您只需要这样做,如果有 .after() 循环,则无法按下开始按钮。

    为此,您必须更改三个函数

    counter() 函数

    我已经更改了代码,所以如果计数器正在运行,那么start_button 将被禁用,当计数器停止运行时,其状态将恢复正常

    def Counter():
        '''Updating hour, minute and seconds'''
        global HOUR, MINUTE, SECOND
    
        if PAUSE is False:
            start_button['state'] = 'disabled' # setting it to disabled if the counter is running
            if SECOND == 59:
                if MINUTE == SECOND == 59:
                    HOUR += 1
    
                if MINUTE == 59:
                    MINUTE = 0
    
                else:
                    MINUTE += 1
    
                SECOND = -1
    
            SECOND += 1
    
            Time.config(text='{}:{}:{}'.format(str(HOUR).zfill(2), str(MINUTE).zfill(2), str(SECOND).zfill(2)))
            root.after(1000, Counter)
        else:
            start_button['state'] = 'normal' # setting it to normal if the counter stops
    

    pause()reset() 函数

    您必须取消将start_button 的状态设置为正常的功能,因为这将允许在最后一个计数器循环完成之前按下start_button

    def pause():
        '''Command for PAUSE button'''
    
        global PAUSE
    
        PAUSE = True
        pause_button['state'] = 'disabled'
    
    def reset():
        '''Command for RESET button'''
    
        global HOUR, MINUTE, SECOND, PAUSE
    
        PAUSE = True
        pause_button['state'] = 'disabled'
        reset_button['state'] = 'disabled'
        Time['text'] = '00:00:00'
    
        HOUR, MINUTE, SECOND = 0, 0, 0
    

    更新这些功能将消除此错误。 希望这是您正在寻找的答案:)

    【讨论】:

      【解决方案2】:

      您的Counter 函数每次单击都会调用root.after(1000,Counter),并且还会在单击时立即修改Time 标签。当您足够快地单击按钮时,您可以安排多个 root.after 并添加秒数。

      要修改当前脚本,您可以跟踪当前操作,并调用root.after_cancel 暂停操作。

      from tkinter import *
      
      PAUSE = False
      HOUR, MINUTE, SECOND = 0, 0, 0
      action = None #keep track on current action and also avoid click spam
      
      
      def start():
          '''Command for START button'''
      
          global PAUSE, action
      
          PAUSE = False
          ...
          if not action:
              Counter()
      
      
      def pause():
          '''Command for PAUSE button'''
      
          global PAUSE, action
      
          ...
          if action:
              root.after_cancel(action)
              action = None
      
      
      def reset():
          '''Command for RESET button'''
      
          global HOUR, MINUTE, SECOND, PAUSE, action
      
          ...
      
          HOUR, MINUTE, SECOND = 0, 0, 0
          action = None
      
      
      def Counter():
          '''Updating hour, minute and seconds'''
      
          global HOUR, MINUTE, SECOND, action
      
          if PAUSE is False:
              if SECOND == 59:
                  if MINUTE == SECOND == 59:
                      HOUR += 1
      
                  if MINUTE == 59:
                      MINUTE = 0
      
                  else:
                      MINUTE += 1
      
                  SECOND = -1
      
              SECOND += 1
      
              Time.config(text='{}:{}:{}'.format(str(HOUR).zfill(2), str(MINUTE).zfill(2), str(SECOND).zfill(2)))
              action = root.after(1000, Counter)
      
      root = Tk()
      ...
      start_button = Button(root, text='START', font=("Arial", 16), fg='black', width=8, command=lambda: root.after(1000,start)) #to avoid the instant second increment
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-04-02
        • 1970-01-01
        • 1970-01-01
        • 2021-01-23
        • 1970-01-01
        • 2020-07-27
        • 1970-01-01
        相关资源
        最近更新 更多