Python Forum
tkinter lightswitch
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
tkinter lightswitch
#1
Just wanted to share a little program using tkinter and images in hoping maybe it will help someone.



The images:
[Image: on.png][Image: off.png][Image: switch_off.png][Image: switch_on.png]

The code:
#! /usr/bin/env python3

import tkinter as tk
from functools import partial

class MyClass:
    def __init__(self, parent):
        self.parent = parent
        self.parent.columnconfigure(0, weight=1)
        self.parent.rowconfigure(0, weight=1)

        self.frame = tk.Frame(self.parent)
        self.frame.grid(column=0, row=0, sticky='news')
        self.frame.grid_columnconfigure(0, weight=3)
        self.frame.grid_rowconfigure(0, weight=3)

        bulb = tk.PhotoImage(file='off.png')
        bulb.img = bulb

        switch = tk.PhotoImage(file='switch_off.png')
        switch.img = switch

        self.light = tk.Label(self.frame, image=bulb)
        self.light.grid(column=0, row=0, sticky='news')

        self.switch = tk.Label(self.frame, image=switch)
        self.switch.grid(column=0, row=1, sticky='news')
        is_clicked = True
        self.switch.bind('<ButtonRelease-1>', partial(self.lightswitch, is_clicked))
        # self.switch.bind('<ButtonRelease-1>', partial(self.lightswitch, 'off'))


    def lightswitch(self, value, event):
        is_clicked = True
        if value:
            bulb = tk.PhotoImage(file='on.png')
            bulb.img = bulb
            self.light['image'] = bulb
            switch = tk.PhotoImage(file='switch_on.png')
            switch.img = switch
            self.switch['image'] = switch
            self.is_clicked = False
            self.switch.bind('<ButtonRelease-1>', partial(self.lightswitch, self.is_clicked))
        else:
            bulb = tk.PhotoImage(file='off.png')
            bulb.img = bulb
            self.light['image'] = bulb
            switch = tk.PhotoImage(file='switch_off.png')
            switch.img = switch
            self.switch['image'] = switch
            self.is_clicked = True
            self.switch.bind('<ButtonRelease-1>', partial(self.lightswitch, self.is_clicked))



def main():
    root = tk.Tk()
    root.title('Light On/Off')
    root.geometry('+250+200')
    MyClass(root)
    root.mainloop()

if __name__ == '__main__':
    main()
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags


Reply
#2
I like it, I've done another version of it by creating a BoolImageLabel that keeps track of its own state and its own images.
import tkinter as tk


class SwitchApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.title('Light On/Off')
        self.geometry('+250+200')
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

        self.frame = tk.Frame(self)
        self.frame.grid(column=0, row=0, sticky='news')
        self.frame.grid_columnconfigure(0, weight=3)
        self.frame.grid_rowconfigure(0, weight=3)

        self.light = BoolImageLabel('off.png', 'on.png', self.frame)
        self.light.grid(column=0, row=0, sticky='news')

        self.switch = BoolImageLabel(
            'switch_off.png', 'switch_on.png', self.frame)
        self.switch.grid(column=0, row=1, sticky='news')
        self.switch.bind('<Button-1>', self.on_switch_click)

    def on_switch_click(self, event):
        self.switch.toggle_state()
        self.light.state = self.switch.state


class BoolImageLabel(tk.Label):
    def __init__(self, false_image_path, true_image_path, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._state = False
        self._images = {False: false_image_path, True: true_image_path}
        self._set_image()

    def _set_image(self):
        self.photo_image = tk.PhotoImage(file=self._images[self.state])
        self.config(image=self.photo_image)

    def toggle_state(self):
        self.state = not self.state

    @property
    def state(self):
        return self._state

    @state.setter
    def state(self, state):
        self._state = state
        self._set_image()


if __name__ == '__main__':
    switch_app = SwitchApp()
    switch_app.mainloop()
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020