作为子进程倒计时的函数

时间:2018-06-03 03:32:44

标签: python multithreading python-3.x tkinter timer

我遇到了运行Tkinter GUI程序(测验游戏)的问题。虽然用户可以选择4个按钮并且可以选择一个,但我需要一个倒数计时器,它会在时间为零时改变问题。我需要它作为子进程或单独的线程,因为否则用户将无法选择答案。

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

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

2 个答案:

答案 0 :(得分:3)

可能没有必要进行多线程处理:您可以使用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()

示例输出:

Is multi-threading necessary? : No
Is simple better than complicated? : Yes

答案 1 :(得分:1)

您可以使用signal

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

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