Похоже, проблема в том, что параметр bg
не определен при первом создании кнопки; он получает значение, назначенное только после первого нажатия кнопки.
Тогда трудно следовать логике переключения: у вас есть логическое значение self.toggled
, но вы проверяете, является ли кнопка sunken
или нет, чтобы различать состояния ...
Я реорганизовал логику, чтобы ей было легче следовать; в конце концов, переключение - это двоичное изменение из одного состояния в другое. Поэтому я поместил определение состояний ON
и OFF
в теле класса (в два словаря классов), и код переключает две конфигурации при переключении.
В Windows:
import tkinter as tk
class ToggleButton(tk.Button):
ON_config = {'bg': 'green',
'text': 'button is ON',
'relief': 'sunken',
}
OFF_config = {'bg': 'white',
'text': 'button is OFF',
'relief': 'raised',
}
def __init__(self, parent, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
self.toggled = False
self.config = self.OFF_config
self.config_button()
self.bind("<Button-1>", self.toggle)
def toggle(self, *args):
if self.toggled: # True = ON --> toggle to OFF
self.config = self.OFF_config
else:
self.config = self.ON_config
self.toggled = not self.toggled
return self.config_button()
def config_button(self):
self['bg'] = self.config['bg']
self['text'] = self.config['text']
self['relief'] = self.config['relief']
return "break"
def __str__(self):
return f"{self['text']}, {self['bg']}, {self['relief']}"
def button_placeholder():
print('toggling now!')
if __name__ == '__main__':
root = tk.Tk()
button = ToggleButton(root)
button.pack()
root.mainloop()
В OSX:
Там, где фиксирован аспект кнопок, использование tk.Label
может имитировать желаемое поведение:
import tkinter as tk
class ToggleButtonLBL(tk.Label):
ON_config = {'bg': 'green',
'text': 'button is ON',
'relief': 'sunken',
}
OFF_config = {'bg': 'white',
'text': 'button is OFF',
'relief': 'raised',
}
def __init__(self, parent, *args, command=None, **kwargs):
super().__init__(parent, *args, **kwargs)
self.toggled = False
self.config = self.OFF_config
self.config_button()
self.bind("<Button-1>", self._toggle_helper)
self.bind("<ButtonRelease-1>", self._toggle)
self.command = command
def _toggle_helper(self, *args):
return 'break'
def _toggle(self, dummy_event):
self.toggle()
self.cmd()
def toggle(self, *args):
if self.toggled: # True = ON --> toggle to OFF
self.config = self.OFF_config
else:
self.config = self.ON_config
self.toggled = not self.toggled
self.config_button()
return 'break'
def config_button(self):
self['bg'] = self.config['bg']
self['text'] = self.config['text']
self['relief'] = self.config['relief']
return "break"
def __str__(self):
return f"{self['text']}, {self['bg']}, {self['relief']}"
def cmd(self):
self.command()
def button_placeholder():
print('toggling now!')
if __name__ == '__main__':
root = tk.Tk()
button = ToggleButtonLBL(root, command=button_placeholder)
button.pack()
root.mainloop()