Tkinter window background color does not reflect in the window

Question:

I have used time.sleep(5) to see if the changes are reflected in the window.
The window opens in blue color. After I click on the ‘Go’ button it changes to yellow. But why does it not change to green when it enters the function ‘func2’?

import time
import tkinter
global win

def func1():
   global win
   win = tkinter.Tk()
   win.geometry("300x200")
   win.configure(bg='blue')
   time.sleep(5)
   button_win = tkinter.Button(win,text='Go',command=func2)
   button_win.pack()
   print('mainloop')
   win.mainloop()

def func2():
   print("func2")
   global win
   win.configure(bg = 'green')
   time.sleep(5)
   print("in func1")
   time.sleep(5)
   print("func3 call")
   func3()

def func3():
   global win
   time.sleep(5)
   win.configure(bg = 'yellow')

func1()

OUTPUT in console

mainloop
(I click on 'Go' button)
func2
in func1
func3 call
Asked By: Nupur

||

Answers:

Basically what happens is that you don’t return to the mainloop where the commands and all the other fancy stuff happens / get executed. Without processing the e.g win.configure(bg='green') your window won’t get green. So before you change the value of the background color you should make sure to either update_idletasks() or return to the mainloop.

In addition using global in the global namespace makes no sense. Use global only when you want to place a variable in the global namespace, you won’t need it to access the global namespace, cause in the module, everything is routed to the global namespace.

Also take the note that time.sleep stops the mainloop for the amount of sleeping seconds, you should avoid that, out of the same reason your window won’t turn green. The mainloop processes all events and stuff, so your window will become unresponsive.

A working code example is:

import time
import tkinter

def func1():
   global win
   win = tkinter.Tk()
   win.geometry("300x200")
   win.configure(bg='blue')
   button_win = tkinter.Button(win,text='Go',command=func2)
   button_win.pack()
   win.mainloop()

def func2():
   win.configure(bg = 'green')
   win.update_idletasks()
   time.sleep(5)
   func3()

def func3():
    win.configure(bg = 'yellow')
    win.update_idletasks()

func1() 
Answered By: Thingamabobs

EDIT:adding full version of code

First of all, as Trooper Z mentioned, if you are not using threads, u should avoid time.sleep when using tkinter.
Also u should avoid using globals if you don’t have to.

First of all I removed all time.sleeps as we don’t need to. Program already enters inside a loop in mainloop. Also we connected func2 to button. We used lambda to be able to send window as parameter.

def func1():
   win = tkinter.Tk()
   win.geometry("300x200")
   win.configure(bg='blue')
   button_win = tkinter.Button(win,text='Go',command=lambda:func2(win))
   button_win.pack()
   win.mainloop()

in func2 we changed color to green then used after method.
What after do is, wait as long as first parameter in milliseconds(5000 = 5 second in this case) than call function

def func2(win):
   win.configure(bg = 'green')
   win.after(5000,lambda:func3(win))

and this is the func3

def func3(win):
   win.configure(bg = 'yellow')

Full version of code

import tkinter

def func1():
   win = tkinter.Tk()
   win.geometry("300x200")
   win.configure(bg='blue')
   button_win = tkinter.Button(win,text='Go',command=lambda:func2(win))
   button_win.pack()
   win.mainloop()

def func2(win):
   win.configure(bg = 'green')
   win.after(5000,lambda:func3(win))

def func3(win):
   win.configure(bg = 'yellow')

func1()
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.