有没有一种方法可以在不冻结窗口的情况下在窗口内实现倒计时?

时间:2020-05-26 10:07:27

标签: python pysimplegui

import PySimpleGUI as sg
import time
q1 = [
        [sg.Text("Question 1!"), sg.Button("x", visible=False), sg.Text("Time:"), sg.Text(" ", size=(10,1), key="t")],
        [sg.Text("This is where question 1 will be?")],
        [sg.Button("Option 1", key="1",button_color=("#ffffff","#151515")), sg.Button("Option 2", key="2",button_color=("#00ff00", "#151515"))],
        [sg.Button("Option 3", key="3",button_color=("#00ffff", "#151515")), sg.Button("Option 4", key="4",button_color=("#ff00ff", "#151515"))],
        [sg.Button("Submit"), sg.Button("Next Question"), sg.Button("Skip")]
    ]

window = sg.Window("Question 1",q1)

while True:
    event, values = window.Read()
    if event is None:
        break

    seconds = 20
    for i in range(seconds):
        seconds = seconds - i
        window.FindElement("t").Update(seconds)
        time.sleep(1)

我不确定我是否采用正确的方法,但是我想这样做,以便在右上角出现20秒计时器。但是,使用上面的代码,没有计时器启动,并且当您按下按钮时,它将冻结程序20秒钟。

2 个答案:

答案 0 :(得分:0)

您可以选择保存开始时间,并在每次主循环迭代期间计算时间差并更新计时器。
当差异达到20秒时,您将停止并前进至下一个问题,否则可以保护当前的剩余时间或您想使用的剩余时间并重新开始。

这是一个基本示例:

from time import time

TIME_PER_QUESTION = 20.0

# Loop questions
for i in range(3):
  start = time()
  current = time()
  time_left = TIME_PER_QUESTION

  while time_left > 0:
    # Update your interface
    # doStuff()... update()...

    # Spam a bit for testing
    print("Leftover time {:.0f}".format(time_left))

    # Update current time and our timer
    current = time()
    time_left = TIME_PER_QUESTION - (current - start)

当然,您可以添加更多方法来跳出循环并在执行操作时存储剩余时间等,然后进入下一个问题。

有更多方法可以实现这一目标,但这就是您可以做的一件事。 (该技术主要用于游戏中的主循环以及类似的东西)
如评论中所述,如果您愿意的话,也可以使用线程计时器函数来完成它。

编辑
至于更新gui中的文本,我不确定您的操作方式是否可行,但是如果您说从未更新过,请尝试以下方法:

window['t'].update("{:.0f}".format(time_left))

答案 1 :(得分:0)

很抱歉,如果在这篇文章的许多说明中对此进行了讨论。如果是这样,请随意忽略,并为您占用空间感到抱歉。

  1. 切勿在事件循环中放置“睡眠”。在您的window上使用超时。改为读取
  2. 调用window.refresh()以使更改出现在窗口中: https://pysimplegui.readthedocs.io/en/latest/call%20reference/#window 它指出:

当您希望某些东西立即出现在窗口中时(使用此函数时),请使用此调用。如果没有此调用,则在下一个“读取”调用之前,用户对“窗口”所做的更改将对用户不可见

  1. 有一个计时器演示-该演示和定期刷新窗口的概念在整个文档,演示程序以及Trinket中都得到引用。如果您不定期调用“读取”或“刷新”操作,文档将直接涉及使Windows冻结。主要文档在此处讨论了计时器:

https://pysimplegui.readthedocs.io/en/latest/#persistent-window-example-running-timer-that-updates