Tkinter Button with resizable svg background image

I made this code to use an svg image as background of a button that fits the button size and that is also resizable.

So this code go a button with:

  • svg file as background
  • fits the size of the button
  • resizes with the button
  • changes svg images when you click the button

Let’s see what the code looks like:

import tkinter as tk
from PIL import Image, ImageTk
from svglib.svglib import svg2rlg
from reportlab.graphics import renderPM
from io import BytesIO


root = tk.Tk()
root.title("")
root.geometry("400x400")

def iterateimages1(event):
    global img
    b.configure(image=imgToButton("nice.svg"))

def iterateimages2(event):
    global img
    b.configure(image=imgToButton("nice2.svg"))

b = tk.Button(
    root,
    compound="center",
    bg="red",
    font="arial 20",
    text="CLICK ME",
    command=None,
    activeforeground="red",
    activebackground="black",
    )
b.bind("<ButtonPress-1>", iterateimages2)
b.bind("<ButtonRelease-1>", iterateimages1)
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
b.grid(row=0, column=0, sticky="nswe")

def imgToButton(image):
    global img
    b.update()
    bw = b.winfo_width()
    bh = b.winfo_height()
    # SVG CONVERT
    svgfile = svg2rlg(image)
    bytespng = BytesIO()
    renderPM.drawToFile(svgfile, bytespng, fmt="PNG")

    img = Image.open(bytespng)
    img = img.resize((bw, bh), Image.ANTIALIAS)
    img.image = img
    img = ImageTk.PhotoImage(img)
    return img


def resize(event):
    b.configure(image=imgToButton("nice.svg"))

root.bind("<Configure>", resize)



root.mainloop()

Video

New version of the code

Some adjustment to make the code more readable, eventually.

import tkinter as tk
from PIL import Image, ImageTk
from svglib.svglib import svg2rlg
from reportlab.graphics import renderPM
from io import BytesIO


def iterateimages1(event):
    global img
    b.configure(image=fit_svg_to_button("nice.svg"))


def iterateimages2(event):
    global img
    b.configure(image=fit_svg_to_button("nice2.svg"))


def button_update():
    b.update()
    bw = b.winfo_width()
    bh = b.winfo_height()
    return bw, bh


def svg_png(image):
    "svg -> png -> memory -> PIL -> fit button -> Tkinter"

    bw, bh = button_update()
    svgfile = svg2rlg(image)
    bytespng = BytesIO()
    renderPM.drawToFile(svgfile, bytespng, fmt="PNG")
    img = Image.open(bytespng)
    img = img.resize((bw, bh), Image.ANTIALIAS)
    img.image = img
    img = ImageTk.PhotoImage(img)
    return img


def fit_svg_to_button(image):
    "Fit text to button and calls svg_png to fit image"
    global img
    bw = button_update()[0]
    b.configure(font="arial " + str(bw // 10))
    # SVG CONVERT
    img = svg_png(image)
    return img


def resize(event):
    b.configure(image=fit_svg_to_button("nice.svg"))


def main():
    global b

    root = tk.Tk()
    root.title("")
    root.geometry("400x400")
    root.bind("<Configure>", resize)

    fsize = 20 
    b = tk.Button(
        root,
        compound="center",
        bg="red",
        font="arial " + str(fsize),
        text="CLICK ME",
        command=None,
        activeforeground="red",
        activebackground="black",
    )
    b.bind("<ButtonPress-1>", iterateimages2)
    b.bind("<ButtonRelease-1>", iterateimages1)
    root.columnconfigure(0, weight=1)
    root.rowconfigure(0, weight=1)
    b.grid(row=0, column=0, sticky="nswe")

    root.mainloop()

main()

 


Subscribe to the newsletter for updates
Tkinter templates
Avatar My youtube channel

Twitter: @pythonprogrammi - python_pygame

Videos

Speech recognition game

Pygame's Platform Game

Other Pygame's posts

Published by pythonprogramming

Started with basic on the spectrum, loved javascript in the 90ies and python in the 2000, now I am back with python, still making some javascript stuff when needed.