How to Create Custom Image Buttons in Python Tkinter
In this Python Tutorial we will see How to Create a Custom Image Button class that transforms any image into an interactive button with Hover effects, Press effects, Text overlays and Fallback gradient.
What We Are Gonna Use In This Project:
- Python Programming Language.- Tkinter (GUI).
- VS Editor.
- VS Editor.
Project Source Code:
import tkinter as tk
from tkinter import messagebox
from PIL import Image, ImageTk, ImageEnhance
import os
# Set working directory to the script's location
os.chdir(os.path.dirname(os.path.abspath(__file__)))
class CustomImageButton(tk.Canvas):
"""Canvas-based button with image background and text overlay"""
def __init__(self, parent, image_path, text, command=None, width=200, height=60):
# Initialize canvas with specified dimensions and no border
super().__init__(
parent,
width=width,
height=height,
highlightthickness=0
)
self.command = command
self.width = width
self.height = height
# Load and prepare button images for different states
try:
# Load and resize the base image
self.original_image = Image.open(image_path)
self.original_image = self.original_image.resize((width, height),
Image.LANCZOS)
self.normal_image = ImageTk.PhotoImage(self.original_image)
# Create brighter version for hover state (20% brighter)
brightener = ImageEnhance.Brightness(self.original_image)
bright_image = brightener.enhance(1.2)
self.hover_image = ImageTk.PhotoImage(bright_image)
# Create darker version for pressed state (20% darker)
darkener = ImageEnhance.Brightness(self.original_image)
dark_image = darkener.enhance(0.8)
self.pressed_image = ImageTk.PhotoImage(dark_image)
except Exception as e:
print(f"Error loading image: {e}")
# Fall back to gradient if image can't be loaded
self.create_gradient_background()
# Add background image to the canvas
self.normal_bg = self.create_image(0, 0, anchor='nw', image=self.normal_image)
# Add main text centered on the button
self.text_item = self.create_text(
width // 2,
height // 2,
text=text,
fill='black',
font=('Arial', 12, 'bold')
)
# Add a yellow text (on top of the main text) for better readability
# (offset by 1 pixel)
self.create_text(
width // 2 + 1,
height // 2 + 1,
text=text,
fill='yellow',
font=('Arial', 12, 'bold')
)
# Configure mouse event handlers
self.bind('<Enter>', self.on_enter) # Mouse enters button area
self.bind('<Leave>', self.on_leave) # Mouse exits button area
self.bind('<Button-1>', self.on_press) # Mouse button pressed down
self.bind('<ButtonRelease-1>', self.on_release) # Mouse button released
def create_gradient_background(self):
"""Create fallback gradient images if the main image fails to load"""
# Generate a blue gradient from top to bottom
gradient = Image.new('RGB', (self.width, self.height))
for y in range(self.height):
# Calculate color for this row (gradient from blue to lighter blue)
r = int(64 + (14 - 64) * y / self.height)
g = int(134 + (82 - 134) * y / self.height)
b = int(244 + (194 - 244) * y / self.height)
# Apply the color to each pixel in this row
for x in range(self.width):
gradient.putpixel((x, y), (r, g, b))
# Create versions for each button state
self.normal_image = ImageTk.PhotoImage(gradient)
brightener = ImageEnhance.Brightness(gradient)
self.hover_image = ImageTk.PhotoImage(brightener.enhance(1.2))
self.pressed_image = ImageTk.PhotoImage(brightener.enhance(0.8))
def on_enter(self, event):
"""Change to hover image when mouse enters button area"""
self.itemconfig(self.normal_bg, image=self.hover_image)
def on_leave(self, event):
"""Change back to normal image when mouse leaves button area"""
self.itemconfig(self.normal_bg, image=self.normal_image)
def on_press(self, event):
"""Change to pressed image when button is clicked"""
self.itemconfig(self.normal_bg, image=self.pressed_image)
def on_release(self, event):
"""Execute command when button is released and return to hover state"""
self.itemconfig(self.normal_bg, image=self.hover_image)
if self.command:
self.command()
class App(tk.Tk):
"""Main application window"""
def __init__(self):
# Initialize the main window
super().__init__()
self.title("Custom Image Button")
self.geometry("400x300")
# Center the window on screen
screen_width = self.winfo_screenwidth()
screen_height = self.winfo_screenheight()
x = (screen_width - 400) // 2
y = (screen_height - 300) // 2
self.geometry(f"400x300+{x}+{y}")
# Create and add a custom image button
button = CustomImageButton(
self,
"images/coffee-3936903_640.jpg", # Image path (should be in images folder)
"Click Me",
command=self.button_click
)
button.pack(pady=50) # Add button with vertical padding
def button_click(self):
"""Display a message when button is clicked"""
messagebox.showinfo("Click", "Button clicked!")
if __name__ == "__main__":
# Create and run the application
app = App()
app.mainloop()
The Final Result:
Download Projects Source Code
Aucun commentaire:
Enregistrer un commentaire