Python 作为子流程倒计时的函数

Python 作为子流程倒计时的函数,python,multithreading,python-3.x,tkinter,timer,Python,Multithreading,Python 3.x,Tkinter,Timer,我有一个问题,我正在运行Tkinter GUI程序(一个问答游戏)。虽然用户有4个按钮可供选择,可以选择一个,但我需要一个倒计时计时器,当时间为零时,它将改变问题。我需要它作为一个子进程或单独的线程,因为用户将无法选择其他答案 这与其他有关计时器的问题不同,因为这些问题的答案包括[Object]=threading.Timer(numCount,callback),但计时器不会在计数时返回其值 有没有办法做到这一点?我已经尝试了多种方法,包括线程模块和pygame时钟(:D)。可能不需要多线程:

我有一个问题,我正在运行Tkinter GUI程序(一个问答游戏)。虽然用户有4个按钮可供选择,可以选择一个,但我需要一个倒计时计时器,当时间为零时,它将改变问题。我需要它作为一个子进程或单独的线程,因为用户将无法选择其他答案

这与其他有关计时器的问题不同,因为这些问题的答案包括
[Object]=threading.Timer(numCount,callback)
,但计时器不会在计数时返回其值


有没有办法做到这一点?我已经尝试了多种方法,包括线程模块和pygame时钟(:D)。

可能不需要多线程:您可以使用
after
方法在时间流逝时更改问题,同时保持GUI的反应性:

在下面的示例中,问题每10秒更改一次

import tkinter as tk


def countdown(t):
    cdn['text'] = f'{t}'
    if t > 0:
        root.after(1000, countdown, t-1)


def change_question(idx):
    lbl['text'] = questions[idx % 2]
    root.after(10000, change_question, idx+1)
    countdown(10)


def clickme(t):
    print(f"{lbl['text']} : {t}")


if __name__ == '__main__':

    questions = ['Is multi-threading necessary?', 'Is simple better than complicated?']
    root = tk.Tk()
    bt1 = tk.Button(root, text='Yes', command=lambda: clickme('Yes'))
    bt2 = tk.Button(root, text='No', command=lambda: clickme('No'))
    bt3 = tk.Button(root, text='Maybe', command=lambda: clickme('Maybe'))
    bt4 = tk.Button(root, text='No Idea', command=lambda: clickme('No Idea'))
    lbl = tk.Label(root, text='')
    cdn = tk.Label(root, text='')
    cdn.pack()

    lbl.pack()
    bt1.pack()
    bt2.pack()
    bt3.pack()
    bt4.pack()
    change_question(0)
    root.mainloop()
样本输出:
多线程可能不是必需的:您可以使用
after
方法在时间过去后更改问题,同时保持GUI的反应性:

在下面的示例中,问题每10秒更改一次

import tkinter as tk


def countdown(t):
    cdn['text'] = f'{t}'
    if t > 0:
        root.after(1000, countdown, t-1)


def change_question(idx):
    lbl['text'] = questions[idx % 2]
    root.after(10000, change_question, idx+1)
    countdown(10)


def clickme(t):
    print(f"{lbl['text']} : {t}")


if __name__ == '__main__':

    questions = ['Is multi-threading necessary?', 'Is simple better than complicated?']
    root = tk.Tk()
    bt1 = tk.Button(root, text='Yes', command=lambda: clickme('Yes'))
    bt2 = tk.Button(root, text='No', command=lambda: clickme('No'))
    bt3 = tk.Button(root, text='Maybe', command=lambda: clickme('Maybe'))
    bt4 = tk.Button(root, text='No Idea', command=lambda: clickme('No Idea'))
    lbl = tk.Label(root, text='')
    cdn = tk.Label(root, text='')
    cdn.pack()

    lbl.pack()
    bt1.pack()
    bt2.pack()
    bt3.pack()
    bt4.pack()
    change_question(0)
    root.mainloop()
样本输出:
您可以使用
信号

def myfunc(sig, frame):
    print("timer fired")

signal.signal(signal.SIGALRM, myfunc)
signal.alarm(4) # seconds

您可以使用
信号

def myfunc(sig, frame):
    print("timer fired")

signal.signal(signal.SIGALRM, myfunc)
signal.alarm(4) # seconds

不,您不需要子进程或线程。在tkinter中使用
after
方法实现计时器是很简单的。不,您不需要子进程或线程。使用
after
方法在tkinter中实现计时器非常简单。通过删除lambda:
根,可以稍微降低对
after
的调用的复杂性。after(10000,change\u question,idx+1)
。按钮命令也可以缩短一点,因为在任何情况下,
t
都是常量:
button(…,command=lambda:clickme('Yes'))
。很好,谢谢。我不知道参数可以在lambda构造之外的之后通过
传递。@Reblochon Masque我知道这一点。但我希望当前时间计数显示在右上角,而after方法无法实现这一点。还有其他方法吗?对不起,我添加了一个倒计时标签,它也使用了
after
方法。您可以通过删除lambda:
root.after(10000,change\u question,idx+1)
稍微简化对
after的调用。按钮命令也可以缩短一点,因为在任何情况下,
t
都是常量:
button(…,command=lambda:clickme('Yes'))
。很好,谢谢。我不知道参数可以在lambda构造之外的
之后通过
传递。@Reblochon Masque我知道这一点。但我希望当前时间计数显示在右上角,而after方法无法实现这一点。还有其他方法吗?对不起,我添加了一个倒计时标签,它也使用了
after
方法这对我不起作用。没有打印任何内容,进程似乎在持续运行,因为程序没有关闭。这对我不起作用。由于程序未关闭,因此未打印任何内容,进程似乎在持续运行。