Python 触发按钮时如何在按钮上设置倒计时

Python 触发按钮时如何在按钮上设置倒计时,python,tkinter,Python,Tkinter,因此,我试图创建一个mm:ss形式的倒计时计时器,并在按下按钮时以1秒的间隔开始倒计时。我试图让计时器显示在按钮上也倒计时。这就是我目前所拥有的,我不知道该怎么做 import tkinter as tk root = tk.Tk() monsterTimer = '00:02' def converter(sec): m, s = map(int, sec.split(":")) sec = m * 60 + s sec -= 1 m, s = divmod(s

因此,我试图创建一个mm:ss形式的倒计时计时器,并在按下按钮时以1秒的间隔开始倒计时。我试图让计时器显示在按钮上也倒计时。这就是我目前所拥有的,我不知道该怎么做

import tkinter as tk
root = tk.Tk()
monsterTimer = '00:02'
def converter(sec):
    m, s = map(int, sec.split(":"))
    sec = m * 60 + s
    sec -= 1
    m, s = divmod(sec, 60)
    sec = (f'{m:02d}:{s:02d}')
    if sec != '00:00':
        sec = 'end'
    root.after(1000, converter)
    return sec

def update_btn_text():
    btn_text.set(converter(monsterTimer))

btn_text = tk.StringVar()
btn_text.set(monsterTimer)
btn = tk.Button(root, textvariable=btn_text, command=lambda: update_btn_text())
btn.place(x=10, y=10)
root.mainloop()
请尝试以下代码:

import tkinter as tk
import time
import threading

root = tk.Tk()
monsterTimer = '00:00'
run_tm = 5


def update_btn_text(sec):
    while sec:
        m, s = divmod(sec, 60)
        m, s = str(m).zfill(2), str(s).zfill(2)
        tm = f'{m}:{s}'
        btn_text.set(tm)
        time.sleep(1)
        sec -= 1
    btn_text.set("00:00")


def startThread(t):
    th1 = threading.Thread(target=update_btn_text, args=(t, ))
    th1.start()


btn_text = tk.StringVar()
btn_text.set(monsterTimer)
btn = tk.Button(root, textvariable=btn_text, command=lambda: startThread(run_tm))
btn.place(x=50, y=50)
root.mainloop()

您的解决方案很接近,在之后使用
而不是线程是正确的方法

第一个问题是,当您使用
root.after
时,您正在调用
converter
,但没有传入参数。您需要将该行更改为如下所示,它将每秒调用
converter(sec)

root.after(1000, converter, sec)
另一个问题是,如果不是00:00,则将
设置为
'end'
。只有在00:00时才需要设置:

第三,在调用
之后的
之前,您需要更新
转换器中的按钮文本:

...
btn_text.set(sec)
root.after(1000, converter, sec)
最后,您根本不需要
update\u btn
。它可以被删除,您可以通过按钮命令调用
转换器

btn = tk.Button(root, textvariable=btn_text, command=lambda: converter(monsterTimer))

综上所述,它看起来是这样的:

import tkinter as tk
root = tk.Tk()
monsterTimer = '00:10'
def converter(sec):
    m, s = map(int, sec.split(":"))
    sec = m * 60 + s
    sec -= 1
    m, s = divmod(sec, 60)
    sec = (f'{m:02d}:{s:02d}')
    if sec == '00:00':
        sec = 'end'
    btn_text.set(sec)
    if sec != "end":
        root.after(1000, converter, sec)

btn_text = tk.StringVar()
btn_text.set(monsterTimer)
btn = tk.Button(root, textvariable=btn_text, command=lambda: converter(monsterTimer))
btn.place(x=10, y=10)
root.mainloop()

它创建了另一个线程,我们用来调用
update\u btn\u text
函数。如果我们使用主线程执行此操作,IDK why但tkinter按钮冻结。请包含运行此代码时遇到的错误。
import tkinter as tk
root = tk.Tk()
monsterTimer = '00:10'
def converter(sec):
    m, s = map(int, sec.split(":"))
    sec = m * 60 + s
    sec -= 1
    m, s = divmod(sec, 60)
    sec = (f'{m:02d}:{s:02d}')
    if sec == '00:00':
        sec = 'end'
    btn_text.set(sec)
    if sec != "end":
        root.after(1000, converter, sec)

btn_text = tk.StringVar()
btn_text.set(monsterTimer)
btn = tk.Button(root, textvariable=btn_text, command=lambda: converter(monsterTimer))
btn.place(x=10, y=10)
root.mainloop()