TomSchimansky / CustomTkinter

A modern and customizable python UI-library based on Tkinter
MIT License
10.8k stars 1.03k forks source link

Image Button Transparent Borders #2381

Closed Anormalll closed 2 months ago

Anormalll commented 2 months ago

Trying to create a image button with transparent or no borders but the borders keep coming up with white color

Code: def create_image_button(parent_frame, text, command=None, fg_color='transparent', border_width=0, border_spacing=0, corner_radius=0, hover=False,image=None, width=120, height=120): button = ctk.CTkButton(parent_frame, text=text, command=command, font=button_font, image=image, width=width, height=height, hover=hover, fg_color=fg_color, border_width=border_width, border_spacing= border_spacing, corner_radius=corner_radius)

Image: 2024-04-16_17-13-05

rigvedmaanas commented 2 months ago

Hi @Anormalll,

I found that button_font is not defined. Maybe that might be your issue. Can you provide a small code snippet which has this same issue so that we can also test this in our end. It would be better if you put the code in "```" for syntax highlighting.

Anormalll commented 2 months ago

Thank you for the answer but it was defined.

Code snippet:

import customtkinter as ctk
import os
from tkinter import ttk, messagebox, Canvas, VERTICAL
import tkinter as tk

button_font = ("Arial", 20, "bold")
def create_image_button(parent_frame, text, command=None, fg_color='transparent', border_width=0, border_spacing=0,
                                         corner_radius=0, hover=False,image=None, width=120, height=120, ):
    button = ctk.CTkButton(parent_frame, text=text, command=command,
                                          font=button_font, image=image, width=width, height=height,hover=hover, fg_color=fg_color,
                                          border_width=border_width, border_spacing= border_spacing, corner_radius=corner_radius)

    return button

def load_image(file_path):
        try:
            return tk.PhotoImage(file=file_path)
        except tk.TclError:
            messagebox.showerror("Error",
                                 "UI error")
            return None
            sys.exit()

ctk.set_appearance_mode("System")  # Modes: "System" (standard), "Dark", "Light"
ctk.set_default_color_theme("blue")  # Themes: "blue" (standard), "green", "dark-blue"

# Create the main application window
app = ctk.CTk()

screen_width = app.winfo_screenwidth()
screen_height = app.winfo_screenheight()
app.geometry("1024x600+0+0")

img_next = load_image(os.path.join(".", "Images", "Next.png"))
img_background = load_image(os.path.join(".", "Images", "Arkaplan.png"))

def main_screen():
    # Clear the window
    for widget in app.winfo_children():
        widget.destroy()

    # Set the background image for the main screen
    background_label = ctk.CTkLabel(app, image=img_background)
    background_label.place(relwidth=1, relheight=1)

    next_button = create_image_button(app, image=img_next, command=print("next button"), text="")
    next_button.place(relx=0.85, rely=0.95, anchor='sw')

# Build the login screen
main_screen()

# Start the application
app.mainloop()
rigvedmaanas commented 2 months ago

Hi @Anormalll,

The above mentioned issue was not there when I tried your code snippet.

Image: Screenshot 2024-04-17 at 9 09 27 PM

I created an image similar to yours. Please try using this image so that we can make sure that its not the problem of your image.

next

Anormalll commented 2 months ago

@rigvedmaanas can you also try same code with an image background not with a static color?

2024-04-18_00-09-37

rigvedmaanas commented 2 months ago

@Anormalll this was my result after using a background image.

Screenshot 2024-04-18 at 1 40 23 PM

Your are using tk.PhotoImage. It is recommended that you use CTkImage instead. Maybe that's the issue Try using this function. You need to pip install Pillow library.

from PIL import Image
def load_image(file_path):
        try:
            img = Image.open(file_path)
            return ctk.CTkImage(img, size=img.size)
        except Exception as e:
            messagebox.showerror("Error",
                                 f"UI error: {e}")
            return None
            sys.exit()
Anormalll commented 2 months ago

@rigvedmaanas Yep tried that one also but the result is same

2024-04-19_15-30-12

Dont know what am I missing...

import customtkinter as ctk
import os
from tkinter import ttk, messagebox, Canvas, VERTICAL
import tkinter as tk
from PIL import Image, ImageTk

button_font = ("Arial", 20, "bold")
def create_image_button(parent_frame, text, command=None, fg_color='transparent', border_width=0, border_spacing=0,
                                         corner_radius=0, hover=False,image=None, width=100, height=100):
    button = ctk.CTkButton(parent_frame, text=text, command=command,
                                          font=button_font, image=image, width=width, height=height,hover=hover, fg_color=fg_color,
                                          border_width=border_width, border_spacing= border_spacing, corner_radius=corner_radius)

    return button

def load_image(file_path):
    """Load an image using PIL and return a tkinter-compatible photo image."""
    try:
        # Load the image with Pillow
        img = Image.open(file_path)
        return ctk.CTkImage(img, size=img.size)
    except Exception as e:
        messagebox.showerror("Error", f"Failed to load image: {str(e)}")
        return None

ctk.set_appearance_mode("System")  # Modes: "System" (standard), "Dark", "Light"
ctk.set_default_color_theme("blue")  # Themes: "blue" (standard), "green", "dark-blue"

# Create the main application window
app = ctk.CTk()

screen_width = app.winfo_screenwidth()
screen_height = app.winfo_screenheight()
app.geometry("1280x800+0+0")

# Load images using the function
img_next = load_image(os.path.join(".", "Images", "Next.png"))
img_background = load_image(os.path.join(".", "Images", "Arkaplan.png"))

# Define other parts of your GUI application
def main_screen():
    # Clear the window
    for widget in app.winfo_children():
        widget.destroy()

    # Set the background image for the main screen
    background_label = ctk.CTkLabel(app, image=img_background)
    background_label.place(relwidth=1, relheight=1)

    next_button = create_image_button(app, image=img_next, command=lambda: print("next button"), text="")
    next_button.place(relx=0.85, rely=0.95, anchor='sw')

# Build the login screen
main_screen()

# Start the application
app.mainloop()
rigvedmaanas commented 2 months ago

@Anormalll This issue is strange. Can you try placing just the button with just image, text and fg_color. By default border width of a button in theme blue is 0. That's why border_width=0 is not given.

Example Code:

from customtkinter import *
from PIL import Image

set_appearance_mode("System")
set_default_color_theme("blue")

root = CTk()
root.geometry("500x500")

img = Image.open("path/to/image")
image = CTkImage(img, size=img.size)
btn = CTkButton(root, image=image, text="", fg_color="transparent")
btn.pack(expand=True)

root.mainloop()
Anormalll commented 2 months ago

@rigvedmaanas This way it works because there is no image background. The problem occurs when you placed an image button on a image background. You can not change or make the 4 corners of button "transparent"(same as background) if the button image is circular.

github

rigvedmaanas commented 2 months ago

@Anormalll If you are on windows then you can take a look at this issue #2214. This will allow you to make the background of a widget transparent.

Anormalll commented 2 months ago

@rigvedmaanas Thank you thats the solution but my project is on linux guess have to wait for the solution.