Python Forum
[Tkinter] Tk window not displaying until loop has completed
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] Tk window not displaying until loop has completed
#1
Hi, I'm new to python and Tkinter (as in two days in!), so appreciate this may be a pretty obvious mistake I'm making. Why is it that if I have a loop(s) in my code that the Tk window doesn't display until the loop(s) has gone through all it's iterations. What I want is for the window to display at the start so that I can then view the result of each iteration in the window. Here's a small sample program to show what I mean. If you run it yourself you'll see the lag before the window opens.

from tkinter import *

root = Tk()

for column in range (0, 50):
    
    for row in range (0, 40):
        
        #calculate next number from row and column
        number = row+(column*40)
        #create label
        myLabel = Label(root, text=str(number))
        #display label
        myLabel.grid(row=row, column=column)
    
root.mainloop()
Reply
#2
tkinter updates things when your program is idle. Normally this is what you want to happen. If you have something that takes a long time to complete you should break it up into smaller pieces of processing, or run it in a thread or parallel process. This way your GUI is still responsive to user actions.

You will not see anything before mainloop() is called. Here is a much longer delay with a lot less going on.
import tkinter as tk
import time

start = time.time()
root = tk.Tk()
tk.Label(root, text='Hello World!').pack()
print(time.time() - start)
time.sleep(5)
root.mainloop()
If you don't care about having a responsive interface, you can call update() to update your widgets.
import tkinter as tk
import time

start = time.time()
root = tk.Tk()
tk.Label(root, text='Hello World!').pack()
root.update()
print(time.time() - start)
time.sleep(5)
root.mainloop()
This draws the window right away, but the window is unresponsive and you get a busy cursor until the program wakes up from its 5 second nap.
Reply
#3
OK. So, I added a root.update() inside the loops of my sample program which works to a point. It severely slows down the program though. Especially as it gets towards the end and there's more information to update. Isn't there a way to just update what is being added to the window, rather than updating the entire window every time through the loop?
Reply
#4
You shouldn't be using update at all. You shouldn't be writing programs that have a flow that requires something like update.

You can speed things up (make things less horrible) by updating less often. Maybe after 10 labels or 50 labels.
Reply
#5
P.S. The ultimate goal is to have an image (or images) that smoothly move around inside the already existing window. In order to create the smoothness and reduce lag, I only want the image to be updated and not the entire window.
Reply
#6
I do not understand what you are trying to do. Your example is nothing like what you claim. Are you adding images or moving images, or are you changing images to give the impression of motion? What kind of program are you writing? What are these images? Why are they moving?

If you plan to move things with a loop you are going to have a problem. As I mentioned before, GUI programs are not supposed to wait. No long for loops. To allow any kind of interaction, your program will have to break the "moving image" into "moving image in baby steps" and periodically call a function to update the image position. In tkinter this is usually done using the after() function. Using after() you call a function every 50 milliseconds or so. The function moves your image, schedules itself to run again in 50 milliseconds (using after()), and returns. Now that mainloop() is not blocked from executing, changes made in the move function quickly appear in the window.
Ganga likes this post
Reply
#7
Hi, sorry for any confusion. The example was just to show that the window was not showing until after the loop had completed.

The program I am hoping to write is a simulation of ant foraging behaviour. Therefore, the images will be small bitmap ants. They are moving because, well, that's what ants do, especially when they are foraging.

What you suggest with the after() function sounds more like what I'm looking for.

Forgive my ignorance, I haven't done any programming since I was studying in the early 90's using Pascal. I will have to get my head around how the GUI's operate. Thank you for your patience.
Reply
#8
You might want to look at PyGame. It is designed for making games, and games often involve lots of moving images around.

If you want to use tkinter, you should look at canvas. You would still use .after(), but it is easier to move little bitmaps around on a canvas than it is in a frame.
Ganga likes this post
Reply
#9
Ok. There's some very useful pointers there. Thank you for your help.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Interaction between Matplotlib window, Python prompt and TKinter window NorbertMoussy 3 341 Mar-17-2024, 09:37 AM
Last Post: deanhystad
  Trying to make random image loop in Tk window using python Jediguy18 1 3,154 Dec-30-2020, 04:56 AM
Last Post: deanhystad
  Displaying various layouts in a single window arbiel 6 4,013 Nov-08-2020, 09:21 PM
Last Post: arbiel
  tkinter window and turtle window error 1885 3 6,619 Nov-02-2019, 12:18 PM
Last Post: 1885
  update a variable in parent window after closing its toplevel window gray 5 8,974 Mar-20-2017, 10:35 PM
Last Post: Larz60+

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020