Python — кнопка выхода Tkinter в дочернем окне и как она влияет на состояние переключателя

Я новичок, пытаюсь выучить Python с помощью Raspberry Pi. Я писал некоторый код, чтобы попытаться сделать простой эмулятор для добавления piFace на борту.

Есть несколько проблем с этим, и я учусь, когда работаю над ними.

Мой код открывает окно и показывает кнопку-переключатель, которая включает/выключает светодиодное изображение. Я также добавил кнопку, которая открывает дочернее окно. В дочернем окне есть две кнопки. Одна из них — это кнопка включения/выключения, которая включает/выключает светодиодное изображение, а другая — кнопка «Выход».

Моя проблема в том, что когда светодиод «включен», если я использую кнопку «Выход», дочернее окно закрывается, как и должно быть. Но если я снова открою дочернее окно и использую кнопку-переключатель, чтобы включить светодиод, ничего не произойдет. Если я снова нажму кнопку переключения, загорится светодиод.

Я вроде понимаю в чем проблема. Поскольку я закрываю дочернее окно, когда светодиод «включен», состояние кнопки-переключателя все еще находится во включенном состоянии. И когда я снова открываю окно и нажимаю кнопку-переключатель, я просто устанавливаю состояние кнопки-переключателя на ВЫКЛ.

Я не уверен, как решить проблему. Должен ли я смотреть на закрытие окна по-другому и, вероятно, правильно? Должен ли я искать способ предварительной установки состояния тумблера каждый раз, когда дочернее окно открыто? Должен ли я попробовать что-то совершенно другое? Должен ли я вообще остановиться? :-)

Надеюсь, это имеет смысл.

Спасибо за любую помощь.

Вот мой код....

# 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()

person blast_uk    schedule 20.10.2014    source источник


Ответы (1)


Корни проблемы заключаются в том, что вы запускаете дочернее окно, предполагая, что self.signal = False. У меня есть способ определения состояния светодиода, поместите его сюда и проблема решится сама собой, т.е. self.signal = get_led_state().

Теперь, если получить подлинное состояние светодиода невозможно, вам нужно будет сохранить это состояние в другом месте, чтобы оно сохранялось между открытием и закрытием дочернего окна. Один из способов — просто поместить поле signal в класс App. Но я бы поступил следующим образом: создаю класс State, который будет хранить для меня состояние светодиода, например:

class State:
    LED_ON = true

Затем вы будете управлять полем State.LED_ON вместо self.signal, чтобы получить или установить состояние светодиода. Обратите внимание, что это не потокобезопасно, но я считаю, что вам не нужно беспокоиться об этом прямо сейчас :)

person Zaur Nasibov    schedule 20.10.2014
comment
Спасибо - я вроде как понял, о чем вы говорите, и там есть кое-что новое, на что я могу взглянуть, и как мне нужно их реализовать. Для меня это было состояние кнопки-переключателя и то, в каком состоянии она находится, когда я закрываю окно. Поскольку я закрываю дочернее окно с кнопкой-переключателем в состоянии «включено», а затем снова открываю его, рисуя окно с кнопками и изображением в состоянии «выключено», они не совпадают. Если я могу определить состояние кнопки-переключателя, тогда дочернее окно будет иметь правильное состояние. надо поэкспериментировать.... - person blast_uk; 20.10.2014