Есть ли способ реализовать обратный отсчет в окне без зависания окна? - PullRequest
0 голосов
/ 26 мая 2020
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 голосов
/ 29 мая 2020

Приносим извинения, если это обсуждается во многих примечаниях в этом посте. Если это так, не стесняйтесь игнорировать и извините за то, что заняли место.

  1. Никогда не помещайте «сон» в событие l oop. Вместо этого используйте тайм-аут в window.read
  2. Вызовите window.refre sh (), чтобы изменения отображались в вашем окне: https://pysimplegui.readthedocs.io/en/latest/call%20reference/#window В нем указано:

Используйте этот вызов, если вы хотите, чтобы что-то появилось в вашем окне немедленно (как только эта функция вызывается). Без этого вызова ваши изменения в окне не будут видны пользователю до следующего вызова чтения

Существует демонстрация таймера - эта демонстрация и концепция периодического обновления окна упоминаются в документации, в демонстрационной программе, а также на Trinket. В документации прямо говорится о том, что windows зависает, если вы не вызываете периодически read или refre sh. Таймер обсуждается здесь в основных документах:

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

0 голосов
/ 26 мая 2020

Один из вариантов, который у вас есть, - это сохранить время начала и во время каждой итерации основного l oop вы вычисляете разницу во времени и обновляете таймер.
Когда разница достигает 20 секунд, вы останавливаетесь и переходите к следующему вопрос, иначе вы сохраните текущее оставшееся время или все, что вы хотите с ним сделать, и начнете новый.

Вот пример c:

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)

Конечно, вы можете добавить больше способов выйти из l oop и сохранить оставшееся время, пока вы делаете et c. и переходите к следующему вопросу.

Есть и другие способы добиться этого, но это единственное, что вы можете сделать. (Этот метод в основном используется для основных циклов в играх и тому подобном)
Как упоминалось в комментариях, вы, вероятно, также можете сделать это, используя функцию поточного таймера, если хотите.

EDIT
Что касается обновления текста в gui, я не уверен, работает ли ваш способ, но если вы говорите, что он никогда не обновлялся, возможно, попробуйте вместо этого:

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