Home > front end >  Can I create canvas inside the button?
Can I create canvas inside the button?

Time:12-10

from tkinter import *

info = Tk()
btn = Button(info)
canvas = Canvas(btn)
canvas.create_oval(10, 10, 5, 5, fill="red")
canvas.pack()

But it didn't work well. I want to change the image displayed inside the button whenever the program is run, and the image consists of a simple combination of figures(circles and lines).

So I decided to make image with Canvas.

But making Canvas inside the button looks impossible to me. Is it possible?

im = tkinter.PhotoImage(file="photo.png")
btn = Button(info, image=im)

Image is usually added in the button like this ways, I think.

I confirmed the type of object 'im' is <class 'tkinter.PhotoImage'>.

In a different way, can I make <class 'tkinter.PhotoImage'> object with Canvas or matplotlib, or something?

CodePudding user response:

It is easier to make a Clickable Canvas, than make a Canvas Button, (It is possible, but difficult because the canvas blocks the button, so you can't click it). So, make a Canvas which you can click.

Look at this example -

from tkinter import *

def change(event):
    canvas.delete('all')
    canvas.create_rectangle(100, 100, 5, 5, fill="red")

info = Tk()
canvas = Canvas(info,bg='white')
canvas.create_oval(100, 100, 5, 5, fill="red")
canvas.pack()

canvas.bind('<Button-1>',change)

info.mainloop()

CodePudding user response:

You can use Pillow.ImageDraw module to do drawings on an image which can be used as the image of a button.

Below is a simple example:

import tkinter as tk
from PIL import Image, ImageTk, ImageDraw

class CanvasButton(tk.Button):
    def __init__(self, master=None, **kwargs):
        super().__init__(master, **kwargs)
        self.image = Image.new('RGBA', (self['width'], self['height']), (0,0,0,0))
        self.canvas = ImageDraw.Draw(self.image)
        self['image'] = self.photo = ImageTk.PhotoImage(self.image)

    def draw(self, item, *args, **kwargs):
        actions = {
            'rect': self.canvas.rectangle,
            'rectangle': self.canvas.rectangle,
            'oval': self.canvas.ellipse,
            'ellipse': self.canvas.ellipse,
            'line': self.canvas.line,
            'polygon': self.canvas.polygon,
            # add more actions you want
        }
        action = actions.get(item, None)
        if action:
            action(*args, **kwargs)
            self.photo.paste(self.image)

root = tk.Tk()

btn = CanvasButton(root, width=100, height=100, bg='white')
btn.pack(padx=10, pady=10)

btn.draw('rect', (10, 10, 50, 30), fill='red')
btn.draw('oval', (30, 30, 80, 50), fill='blue')

root.mainloop()

Result:

enter image description here

Refer official document on ImageDraw for details.

  • Related