Python - кнопка выхода Tkinter в дочернем окне и как она влияет на состояние кнопки переключения
Я новичок, пытающийся изучать Python с Raspberry Pi. Я писал код, чтобы попытаться сделать простой эмулятор для добавления piFace на борту.
Есть несколько проблем с этим, и я учусь, пробираясь через них.
Мой код открывает окно и показывает кнопку переключения, которая включает / выключает светодиодное изображение. Я также добавил кнопку, которая открывает дочернее окно. Дочернее окно имеет две кнопки. Одна - это кнопка включения / выключения, которая включает / выключает изображение на светодиодах, другая - кнопка выхода.
Моя проблема в том, что когда светодиод "включен", если я использую кнопку "Выход", дочернее окно закрывается, как и должно быть. Но если я снова открою дочернее окно и с помощью переключателя включу светодиод, ничего не произойдет. Если я снова нажму кнопку переключения, загорится светодиод.
Я вроде понимаю, в чем проблема. Поскольку я закрываю дочернее окно, когда светодиод включен, состояние кнопки переключения все еще находится во включенном состоянии. И когда я снова открываю окно и нажимаю кнопку переключения, я просто устанавливаю состояние кнопки переключения в положение OFF.
Я не уверен, как решить проблему. Стоит ли смотреть на закрытие окна другим и, возможно, правильным способом? Стоит ли искать способ предустановки состояния тумблера при каждом открытии дочернего окна? Должен ли я попробовать что-то совершенно другое? Должен ли я вообще остановиться?:-)
Я надеюсь, что это имеет смысл.
Спасибо за любую помощь.
Вот мой код....
# 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()
1 ответ
Корни проблемы кроются в том, что вы запускаете дочернее окно, предполагая, чтоself.signal = False
, Если у вас есть способ определения состояния светодиода, поставьте его здесь и проблема сама решится, т.е. self.signal = get_led_state()
,
Теперь, если получить подлинное состояние светодиода невозможно, вам нужно сохранить это состояние где-то еще, чтобы оно сохранялось между открытием и закрытием дочернего окна. Одним из способов было бы просто положить signal
поле в App
учебный класс. Но я бы пошел следующим образом: создание State
класс, который будет держать состояние светодиода для меня, например:
class State:
LED_ON = true
Затем вы будете контролировать State.LED_ON
поле вместо self.signal
получить или установить состояние светодиода. Обратите внимание, что это не потокобезопасно, но я считаю, что вам не нужно беспокоиться об этом прямо сейчас:)