1

I am learning GUI development using Tkinter. I want to show multiple messages on the label which I have stored in a string. I used sleep to view the changes.However only the last message string is shown at execution.

from tkinter import *
import time
master = Tk()


def onClick():
    for i in range(0,len(list_of_str)):
        w.configure(text=list_of_str[i])
        time.sleep(5)

list_of_str = ['first','second','third','fourth','fifth']

w = Label(master, text="Hello, world!")
b = Button(master,text='Click me',command = onClick)
w.pack()
b.pack()



mainloop()

I am a noobie. So thanks for helping !

Mike - SMT
  • 14,784
  • 4
  • 35
  • 79
ALEX MATHEW
  • 251
  • 1
  • 5
  • 13
  • 1
    `tkinter` doesn't work well with `sleep`. Search and use the method `after`. – Lafexlos May 24 '18 at 11:51
  • 1
    Possible duplicate of [How to create a timer using tkinter?](https://stackoverflow.com/questions/2400262/how-to-create-a-timer-using-tkinter) – Lafexlos May 24 '18 at 11:54
  • Yes. This solved my problem. Thanks! – ALEX MATHEW May 24 '18 at 12:50
  • the `sleep()` method does not worth within a tkinter instance. What it ends up doing is pausing the entire tkinter instance instead of providing a timer. You will want to use the `after()` method as it is specifically meant to provided timed execution of code within tkinter. – Mike - SMT May 24 '18 at 12:55

2 Answers2

1

A simple solution to your problem is to use a combination of the try/except method and using after().

In tkinter sleep() will pause the application instead of providing a timer. For tkinter you want to use the after() method to scheduled an event after a set amount of time instead. The after() method is meant for this exact problem and is what you will always use in tkinter for a delayed event.

In my below example I modified your onClick function to take 1 argument and to use that in our after() method to select the next item in the list after 5 seconds. Note that for the after() method time is done in milliseconds so 5000 is 5 seconds.

from tkinter import *


master = Tk()

def onClick(ndex):
    try:
        w.configure(text=list_of_str[ndex])
        master.after(5000, onClick, ndex+1)
    except:
        print("End of list")

list_of_str = ['first','second','third','fourth','fifth']

w = Label(master, text="Hello, world!")
b = Button(master,text='Click me',command = lambda: onClick(0))
w.pack()
b.pack()

mainloop()
Mike - SMT
  • 14,784
  • 4
  • 35
  • 79
0

I think you want this:

from tkinter import *
import time
master = Tk()

global i
i = 0

def onClick():
    master.after(1, change)      

def change():
    global i
    if i == len(list_of_str):
        pass
    else:
        w.configure(text=list_of_str[i])
        i += 1
        master.after(1000, onClick)

list_of_str = ['first','second','third','fourth','fifth']

w = Label(master, text="Hello, world!")
b = Button(master,text='Click me',command = onClick)
w.pack()
b.pack()

mainloop()

time.sleep is a no-no in tkinter. I advise you make your gui in a class and it wil be easier.

example with class:

import tkinter as tk
from tkinter import *

class GUI:

    def __init__(self, master):
        self.list_of_str = ['first','second','third','fourth','fifth']
        self.count = 0
        self.master = master
        self.w = Label(master, text="Hello, world!")
        self.w.pack()
        self.b = Button(master,text='Click me',command = self.onClick)
        self.b.pack()

    def onClick(self, event=None):
        if self.count == len(self.list_of_str):
            pass
        else:
            self.w.configure(text=self.list_of_str[self.count])
            self.count += 1
            self.master.after(1000, self.onClick)

def main(): 
    root = tk.Tk()
    app = GUI(root)
    root.mainloop()

if __name__ == '__main__':
    main()
kavko
  • 2,751
  • 13
  • 27
  • 1
    I agree that writing in a class is good practice but please provide some details on the changes you made to their code and why you think these are a good idea. Code only answer do not help much in understanding why your code is "better" or a good option. – Mike - SMT May 24 '18 at 12:50
  • This was just a sample problem I made up. I needed to understand why time.sleep wasn't working. Thanks – ALEX MATHEW May 24 '18 at 12:51
  • @Mike I have update the answer with an example code in class. Cheers! – kavko May 24 '18 at 12:57
  • Thanks @Mike. That makes it a lot easier. – ALEX MATHEW May 24 '18 at 13:10
  • I think if you would add some details as to what your changes are and why you made them that this would be a good answer and I would be able to upvote this. – Mike - SMT May 24 '18 at 13:21