Python Forum
Tkinter Image buttons
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Tkinter Image buttons
#1
Using Yoriz's BoolImage class from this post, I made an example of using multiple image buttons with commands. the commands just turn the buttons either on or off. Could be any command or function.

#! /usr/bin/env python3
import tkinter as tk
from functools import partial

class BoolImage(tk.Label):
    def __init__(self, false_img_path, true_img_path, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._state = False
        self._images = {False: false_img_path, True: true_img_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()


class Window:
    def __init__(self, parent):
        self.parent = parent
        self.btns = []
        col = 0
        row = 0
        for i in range(15):
            self.btns.append(BoolImage('../images/buttons/off.png', '../images/buttons/on.png', parent))
            self.btns[i].grid(column=col, row=row, sticky='news')
            self.btns[i]['cursor'] = 'hand2'
            self.btns[i]['text'] = f'Button {i}'
            self.btns[i]['compound'] = 'bottom'
            self.btns[i]['font'] = ('system', 12, 'bold')
            if col >= 4:
                col = 0
                row += 1
            else:
                col += 1
            self.btns[i].bind('<Button-1>', partial(self.switch, self.btns[i]))

    def switch(self, btn, event):
        if btn.state:
            btn.state = False
        else:
            btn.state = True

def main():
    root = tk.Tk()
    root['padx'] = 8
    root['pady'] = 4
    Window(root)
    root.mainloop()

main()
BashBedlam likes this post
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
You
  • could use 2 for loops for the row and col.
  • could apply all the BoolImage parameters in the init
  • don't really need to use partial, the event has a pointer to the widget that triggered the event.
  • don't need the if statement in the event handler to find the current state to then choose what to change it to, just use the toggle_state method.

#! /usr/bin/env python3
import tkinter as tk


class BoolImage(tk.Label):
    def __init__(self, false_img_path, true_img_path, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._state = False
        self._images = {False: false_img_path, True: true_img_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()


class Window:
    def __init__(self, parent):
        self.parent = parent
        self.btns = []
        for row in range(3):
            btns_row = []
            for col in range(5):
                btn = BoolImage(
                    "../images/buttons/off.png",
                    "../images/buttons/on.png",
                    parent,
                    cursor="hand2",
                    text=f"Button {row}:{col}",
                    compound="bottom",
                    font=("system", 12, "bold"),
                )
                btn.grid(column=col, row=row, sticky="news")
                btn.bind("<Button-1>", self.switch)
                btns_row.append(btn)
            self.btns.append(btns_row)

    def switch(self, event):
        event.widget.toggle_state()


def main():
    root = tk.Tk()
    root.config(padx=8, pady=4)
    Window(root)
    root.mainloop()


if __name__ == "__main__":
    main()
menator01 likes this post
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Raw Image Data Viewer using tkinter menator01 1 3,949 Sep-07-2021, 07:08 PM
Last Post: menator01

Forum Jump:

User Panel Messages

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