pythonimagetkintertkinter-canvaspython-class

How to display an image with classes in tkinter?


import tkinter as tk
from PIL import ImageTk, Image

window = tk.Tk()
window.geometry("300x300")
canvas = tk.Canvas(window, width=300, height=300,bg="red")
canvas.pack()

class Button():
    def __init__(self, x, y, canv):
        self.img = ImageTk.PhotoImage(Image.open("Hover.png"))
        canv.create_image(x, y, image=self.img, anchor="nw")

Button(0, 0, canvas)

window.mainloop()

I am trying to display an image in python using the tkinter canvas option. However, if I input it in a class, like below, it doesn't give an error but also doesn't show my image. Pls solve this for me without put the canvas inside of the class


Solution

  • import tkinter as tk
    from PIL import ImageTk, Image
    
    
    class Button:
        def __init__(self, x, y, canv):
            self.img = ImageTk.PhotoImage(Image.open("Hover.png"))
            self.canv = canv
            self.canv.create_image(x, y, image=self.img, anchor="nw")
            self.canv.image = self.img
    
    window = tk.Tk()
    window.geometry("300x300")
    canv = tk.Canvas(window, width=300, height=300, bg="red")
    canv.pack()
    
    Button(0, 0, canv)
    
    window.mainloop()
    
    

    Style

    You can also style it by setting positions and scale:

    import tkinter as tk
    from PIL import ImageTk, Image
    
    
    class Button:
        def __init__(self, x, y, canv, img_path, scale=100):
            self.canv = canv
            self.img_path = img_path
            self.scale = scale / 100.0
            self.set_scale()
            self.border = self.canv.create_rectangle(
                x - 5,
                y - 5,
                x + self.img.width() + 5,
                y + self.img.height() + 5,
                outline="white", width=5)
    
            self.img_id = self.canv.create_image(x, y, image=self.img, anchor="nw")
    
            self.canv.tag_bind(self.img_id, "<Enter>", self.hover)
            self.canv.tag_bind(self.img_id, "<Leave>", self.unhover)
    
        def set_scale(self):
            orig = Image.open(self.img_path)
            w, h = orig.size
            sw, sh = int(w * self.scale), int(h * self.scale)
            resized = orig.resize((sw, sh), Image.LANCZOS)
            self.img = ImageTk.PhotoImage(resized)
    
        def set_pos(self, x, y):
            self.canv.coords(self.img_id, x, y)
            self.canv.coords(self.border, x - 5, y - 5, x + self.img.width() + 5, y + self.img.height() + 5)
    
        def hover(self, event):
            self.canv.itemconfig(self.border, outline="yellow")
    
        def unhover(self, event):
            self.canv.itemconfig(self.border, outline="white")
    
    
    window = tk.Tk()
    window.geometry("300x300")
    canv = tk.Canvas(window, width=300, height=300, bg="red")
    canv.pack()
    
    button = Button(0, 0, canv, "hover.png", 30)
    button.set_pos(25, 25)
    
    window.mainloop()