4

I want to use a for-loop to update a text using PySimpleGUI (Python) but it just updates the text to the last word of the array.

This is my code:

from time import sleep
import PySimpleGUI as sg

sg.theme('dark grey 9')

layout = [[sg.Input(key='paragrafo')],
          [sg.Text(size=(0,1), key='text', font=('Verdana', 20), visible=False)],
          [sg.Button('Start', size=(39,1), key='start')]
          ]

window = sg.Window('Fast reader', layout)

while True:
    event, values = window.read()
    if event == sg.WINDOW_CLOSED:
        break
    paragraf = values['paragrafo']
    paragrafo = paragraf.split()
    window['text'].update(visible=True)
    window['start'].update(visible=False)
    window['paragrafo'].update(visible=False)
    for i in range(0, len(paragrafo)):
        sleep(0.08)
        window['text'].update(paragrafo[i])

window.close()
zHary_
  • 75
  • 6
  • 4
    `window.read()` not just get `event, values`, also update GUI. You should refresh GUI if you want the change updated immediately, so put statement `window.refresh()` after your update in `for` loop, otherwise, only lastest state shown until `window.read()`. – Jason Yang Apr 03 '21 at 06:22
  • 1
    If I may expand on Jason's answer, when you call `update`, all that does is send a message to the text control that it needs to update itself. The result will not actually be drawn until you process the pending events by calling `window.read()`. If you want the display to update immediately, you need to call `window.refresh()`. – Tim Roberts Apr 05 '21 at 18:09

1 Answers1

0

Are you trying to update a text element in a PySimpleGUI window using a for-loop to display each word from the input paragraph one by one? But the text is only updating to the last word of the array. :(

ig the issue here is that the for-loop is updating the text element too quickly, and since the loop is executed rapidly, you only see the final word in the text element. To achieve the desired effect of displaying each word with a slight delay, you can use the time.sleep() function.

I suppose this should be fine, even though it is a rag-tag and makeshifter solution:

from time import sleep
import PySimpleGUI as sg

sg.theme('dark grey 9')

layout = [[sg.Input(key='paragrafo')],
          [sg.Text(size=(0,1), key='text', font=('Verdana', 20), visible=False)],
          [sg.Button('Start', size=(39,1), key='start')]
          ]

window = sg.Window('Fast reader', layout)

while True:
    event, values = window.read()
    if event == sg.WINDOW_CLOSED:
        break
    paragraf = values['paragrafo']
    paragrafo = paragraf.split()
    window['text'].update(visible=True)
    window['start'].update(visible=False)
    window['paragrafo'].update(visible=False)
    for i in range(0, len(paragrafo)):
        sleep(0.5)  # Adjust the sleep time as needed
        window['text'].update(paragrafo[i])
        window.refresh()  # Update the window immediately

window.close()

Sooo here I've added window.refresh() after updating the text element so that the window is updated immediately with the new text. I've increased the sleep time to 0.5 seconds. But it's your choice.

But yeah, using sleep() might cause your UI to pause (become unresponsive) during the loop. For a cooler solution use multi-threading to update the text element without blocking the main event loop. Best of luck!!

Xephonine
  • 49
  • 7