I'm a newbie trying to learn Python with the Raspberry Pi. I've been writing some code to try to make a simple emulator for the piFace add on board.
There are a few issues with it and I'm learning as I work my way through them.
My code opens a window and shows a toggle button which toggles an LED image on/off. I also added a button that opens a child window. The child window has two buttons. One is a on/off toggle button that toggles an LED image on/off, the other is an Exit button.
My problem is that when the LED is 'on' if I use the Exit button the child window closes, as it should. But if I re-open the child window and use the toggle button to turn the LED on, nothing happens. If I press the toggle button again the LED then comes on.
I kind of understand what the problem is. Because I close the child window when the LED is 'on' the toggle button state is still in the ON state. And, when I re-open the window and click the toggle button I'm just setting the toggle button state to OFF.
I'm not sure how to address the problem. Should I look at closing the window a different and probably correct way? Should I look at a way of presetting the state of the toggle switch each time the child window is open? Should I try something completely different? Should I stop altogether? :-)
I hope that makes some sense.
Thanks for any help.
Here's my code....
# Idle 10_01_2014_GUI label image toggle
from time import sleep
from Tkinter import *
import Tkinter as tk
import threading
class App:
def __init__(self, master):
self.master=master
frame = Frame(master)
frame.pack()
Label(frame, text='Turn LED ON').grid(row=0, column=0)
Label(frame, text='Turn LED OFF').grid(row=0, column=1)
self.button0 = Button(frame, text='LED 0 OFF', command=self.convert0)
self.button0.grid(row=2, column=0)
self.LED0 = Label(frame, image=logo2)
self.LED0.grid(row=2, column=1)
self.buttonnewwindow = Button(frame, text='Knight Rider TEST', command=self.new_window)
self.buttonnewwindow.grid(row=10, column=0)
self.button8 = Button(frame, text='Exit', command=quit)
self.button8.grid(row=11, column=0)
def convert0(self, tog=[0]):
tog[0] = not tog[0]
if tog[0]:
print('LED 0 ON')
self.button0.config(text='LED 0 ON')
self.LED0.config(image = logo)
self.LED0.grid(row=2, column=1)
else:
print('LED 0 OFF')
self.button0.config(text='LED 0 OFF')
self.LED0.config(image = logo2)
self.LED0.grid(row=2, column=1)
def new_window(self):
print('New Window')
self.newWindow = tk.Toplevel(self.master)
self.app = App2(self.newWindow)
self.newWindow.grab_set() # I added this line to stop opening multiple new windows
class App2:
def __init__(self, master):
self.signal = False
print('self.signal', self.signal)
self.master=master # I added this line to make the exit button work
frame = Frame(master)
frame.pack()
Label(frame, text='Turn LED ON').grid(row=0, column=0)
Label(frame, text='Turn LED OFF').grid(row=0, column=1)
self.button0 = Button(frame, text='Knight Rider OFF', command=self.convert0)
self.button0.grid(row=2, column=0)
self.LED0 = Label(frame, image=logo2)
self.LED0.grid(row=2, column=1)
self.button9 = Button(frame, text='Exit', command=self.close_window)
self.button9.grid(row=3, column=0)
def convert0(self, tog=[0]):
tog[0] = not tog[0]
if tog[0]:
print('Knight Rider ON')
self.button0.config(text='Knight Rider ON')
self.signal = True
print('self.signal', self.signal)
print('tog[0]', tog[0])
self.LED0.config(image = logo)
else:
print('Knight Rider OFF')
self.button0.config(text='Knight Rider OFF')
self.signal = False
print('self.signal', self.signal)
print('tog[0]', tog[0])
self.LED0.config(image = logo2)
def close_window(self):
print('Knight Rider OFF')
print('self.signal', self.signal)
self.button0.config(text='Knight Rider OFF')
self.LED0.config(image = logo2)
self.signal = False
print('self.signal', self.signal)
sleep(.5)
print('Close Child window')
self.master.destroy() # I added this line to make the exit button work
root = Tk()
logo2 = PhotoImage(file="c:\\Users\\joebloggs\\Downloads\\led-off.gif")
logo = PhotoImage(file="c:\\Users\\joebloggs\\Downloads\\led-on.gif")
root.wm_title('LED on & off program')
app = App(root)
root.mainloop()
The roots of the problem come from the fact that you start the child window assuming that self.signal = False
. I you have a way of detecting the state of the LED, put it here and the problem will solve itself, ie self.signal = get_led_state()
.
Now, if getting the genuine LED state is not possible, then you would need to store that state somewhere else, so that it is preserved between opening and closing the child window. One way would be simply putting the signal
field into the App
class. But I would go as follows: creating a State
class, which will hold the state of the LED for me, eg:
class State:
LED_ON = true
You will then control the State.LED_ON
field instead of self.signal
to get or set the LED state. Note, that it is not thread-safe, but I believe you don't have to worry about that right now :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.