Python
Edison is developing his patented light switch app. He has written all the logic and the window appears and he is very happy with his little creation, however, when he presses his ON button nothing happens. No error is shown and he is at his wits end. He comes to you instead of asking his friend Nikolai to see if you can fix it for him so he doesn't look like a fool. What is he doing wrong and how can it be fixed?
import tkinter as tk
def flip_switch(canv_obj, btn_text):
if btn_text == 'on':
canv_obj.config(bg="#F1F584")
else:
canv_obj.config(bg="#000000")
main_window = tk.Tk()
light = tk.Canvas(main_window, bg="#000000", width=100,
height=50)
light.pack()
on_btn = tk.Button(main_window, text="ON",
command=flip_switch(light, 'on'))
on_btn.pack()
off_btn = tk.Button(main_window, text="OFF",
command=flip_switch(light, 'off'))
off_btn.pack()
main_window.mainloop()
The wrong thing which edison is doing is in the command argument: i.e.
In these lines
on_btn = tk.Button(main_window, text="ON", command=flip_switch(light, 'on'))
off_btn = tk.Button(main_window, text="OFF", command=flip_switch(light, 'off'))
If flip_switch(light,'on') is written in the command argument then , Python will call the flip_switch function before creating the widget, and pass the function’s return value to Tkinter. Tkinter then attempts to convert the return value to a string, and tells Tk to call a function with that name when the button is activated. This is probably not what you wanted.
So on writing this you should pass a function reference to the command argument but you are currently running the function and passing the return value (which is None) instead. that,s why it is not working on clicking the button because the return value(which is none) is going in the command so no action is being performed.
We can overcome to this issue by two methods:
1) By using the helper functions
def light_on():
flip_switch(light, 'on')
def light_off():
flip_switch(light, 'off')
So the code should look like this
-------------------------------------------------------------------------------------------------------------------------------------------------------------
try:
#Python 2
import Tkinter as tk
except ImportError:
#Python 3
import tkinter as tk
def flip_switch(canv_obj, btn_text):
if btn_text == 'on':
canv_obj.config(bg="#F1F584")
else:
canv_obj.config(bg="#000000")
def light_on():
flip_switch(light, 'on')
def light_off():
flip_switch(light, 'off')
main_window = tk.Tk()
light = tk.Canvas(main_window, bg="#000000", width=100,
height=50)
light.pack()
on_btn = tk.Button(main_window, text="ON", command=
light_on)
on_btn.pack()
off_btn = tk.Button(main_window, text="OFF",
command=light_off)
off_btn.pack()
main_window.mainloop()
-------------------------------------------------------------------------------------------------------------------------------------------------------------
2) By using a lambda expression as a link between Tkinter and the flip_switch function: (i.e writing the helper functions inline)
on_btn = tk.Button(main_window, text="ON", command=lambda: flip_switch(light, 'on'))
off_btn = tk.Button(main_window, text="OFF", command=lambda: flip_switch(light, 'off'))
So the code should look like:
-------------------------------------------------------------------------------------------------------------------------------------------------------------
try:
#Python 2
import Tkinter as tk
except ImportError:
#Python 3
import tkinter as tk
def flip_switch(canv_obj, btn_text):
if btn_text == 'on':
canv_obj.config(bg="#F1F584")
else:
canv_obj.config(bg="#000000")
main_window = tk.Tk()
light = tk.Canvas(main_window, bg="#000000", width=100,
height=50)
light.pack()
on_btn = tk.Button(main_window, text="ON",
command=lambda:flip_switch(light, 'on'))
on_btn.pack()
off_btn = tk.Button(main_window, text="OFF",
command=lambda:flip_switch(light, 'off'))
off_btn.pack()
main_window.mainloop()
`
-------------------------------------------------------------------------------------------------------------------------------------------------------------
OUTPUT:
1)Clicking ON

2) Clicking OFF

Python Edison is developing his patented light switch app. He has written all the logic and...