倒计时计时器的速度增加,因为我按启动和暂停按钮一个接一个的几次在tkin

2024-03-29 00:29:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个倒计时脚本,当我一个接一个地按开始和暂停按钮几次时,秒数会快速更新。你知道吗

一开始我认为在开始和暂停按钮之间快速点击会加快秒数,所以我添加了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()

Tags: textdefbuttonrootwidthglobalstartpause
2条回答

At first I thought clicking quickly between start and pause buttons speeds the seconds so I added time.sleep(1) to delay click between the buttons which didn't worked.

问题是,因为在.aftert()方法调用自身之前有一个延迟,所以多次单击start按钮并创建.after(1000, counter)的多个循环。这意味着有许多.after()循环同时发生。要解决这个问题,您只需要使其在.after()循环进行时不能按开始按钮。你知道吗

要做到这一点,你必须改变你的三个职能

The counter() function

我已经更改了代码,因此如果计数器正在运行,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

The pause() and reset() functions

必须取消将start_button的状态设置为normal的功能,因为这将允许在最后一个计数器循环完成之前按下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

更新这些函数将删除此错误。 希望这就是你想要的答案:)

您的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

相关问题 更多 >