diff --git a/Readme.md b/Readme.md index 04e1d1b..f17cbf7 100644 --- a/Readme.md +++ b/Readme.md @@ -94,6 +94,14 @@ colors and removed the round corners, and added a border to the buttons: ![](documentation_images/complex_example_other_style.png) +### CTkButton with images +It's also possible to put an image on a CTkButton. You just have to +pass a PhotoImage object to the CTkButton with the argument ``image``. +You can find an example program ( /simple_test_images.py ), where I +created two buttons with a bell and a settings image on them: + +![](documentation_images/CTkButton_with_images.png) + ## Documentation - CustomTkinter Elements diff --git a/customtkinter/customtkinter_button.py b/customtkinter/customtkinter_button.py index 4503f6d..22bee53 100644 --- a/customtkinter/customtkinter_button.py +++ b/customtkinter/customtkinter_button.py @@ -23,6 +23,7 @@ class CTkButton(tkinter.Frame): text_color=CTkColorManager.TEXT, text="CTkButton", hover=True, + image=None, *args, **kwargs): super().__init__(*args, **kwargs) @@ -75,6 +76,7 @@ class CTkButton(tkinter.Frame): self.function = command self.hover = hover + self.image = image self.configure(width=self.width, height=self.height) @@ -96,7 +98,8 @@ class CTkButton(tkinter.Frame): self.canvas_fg_parts = [] self.canvas_border_parts = [] - self.text_part = None + self.text_label = None + self.image_label = None self.draw() @@ -181,17 +184,49 @@ class CTkButton(tkinter.Frame): else: self.canvas.itemconfig(part, fill=self.border_color, outline=self.border_color, width=0) - self.text_part = self.canvas.create_text(self.width / 2, - self.height / 2, - text=self.text, - font=self.text_font) + # no image provided + if self.image is None: + self.text_label = tkinter.Label(master=self, + text=self.text, + font=self.text_font) + self.text_label.place(relx=0.5, rely=0.5, anchor=tkinter.CENTER) - if type(self.text_color) == tuple and len(self.text_color) == 2: - self.canvas.itemconfig(self.text_part, fill=self.text_color[self.appearance_mode]) + if self.hover is True: + self.text_label.bind("", self.on_enter) + self.text_label.bind("", self.on_leave) + + self.text_label.bind("", self.clicked) + self.text_label.bind("", self.clicked) + + if type(self.text_color) == tuple and len(self.text_color) == 2: + self.text_label.configure(fg=self.text_color[self.appearance_mode]) + else: + self.text_label.configure(fg=self.text_color) + + if type(self.fg_color) == tuple and len(self.fg_color) == 2: + self.text_label.configure(bg=self.fg_color[self.appearance_mode]) + else: + self.text_label.configure(bg=self.fg_color) + + self.set_text(self.text) + + # use image for button else: - self.canvas.itemconfig(self.text_part, fill=self.text_color) + self.image_label = tkinter.Label(master=self, + image=self.image) + self.image_label.place(relx=0.5, rely=0.5, anchor=tkinter.CENTER) - self.set_text(self.text) + if self.hover is True: + self.image_label.bind("", self.on_enter) + self.image_label.bind("", self.on_leave) + + self.image_label.bind("", self.clicked) + self.image_label.bind("", self.clicked) + + if type(self.fg_color) == tuple and len(self.fg_color) == 2: + self.image_label.configure(bg=self.fg_color[self.appearance_mode]) + else: + self.image_label.configure(bg=self.fg_color) def configure_color(self, bg_color=None, fg_color=None, hover_color=None, text_color=None): if bg_color is not None: @@ -211,7 +246,9 @@ class CTkButton(tkinter.Frame): self.draw() def set_text(self, text): - self.canvas.itemconfig(self.text_part, text=text) + self.text = text + if self.text_label is not None: + self.text_label.configure(text=self.text) def on_enter(self, event=0): for part in self.canvas_fg_parts: @@ -220,6 +257,18 @@ class CTkButton(tkinter.Frame): else: self.canvas.itemconfig(part, fill=self.hover_color, width=0) + if self.text_label is not None: + if type(self.fg_color) == tuple and len(self.fg_color) == 2: + self.text_label.configure(bg=self.hover_color[self.appearance_mode]) + else: + self.text_label.configure(bg=self.hover_color) + + if self.image_label is not None: + if type(self.fg_color) == tuple and len(self.fg_color) == 2: + self.image_label.configure(bg=self.hover_color[self.appearance_mode]) + else: + self.image_label.configure(bg=self.hover_color) + def on_leave(self, event=0): for part in self.canvas_fg_parts: if type(self.fg_color) == tuple and len(self.fg_color) == 2: @@ -227,6 +276,18 @@ class CTkButton(tkinter.Frame): else: self.canvas.itemconfig(part, fill=self.fg_color, width=0) + if self.text_label is not None: + if type(self.fg_color) == tuple and len(self.fg_color) == 2: + self.text_label.configure(bg=self.fg_color[self.appearance_mode]) + else: + self.text_label.configure(bg=self.fg_color) + + if self.image_label is not None: + if type(self.fg_color) == tuple and len(self.fg_color) == 2: + self.image_label.configure(bg=self.fg_color[self.appearance_mode]) + else: + self.image_label.configure(bg=self.fg_color) + def clicked(self, event=0): if self.function is not None: self.function() diff --git a/documentation_images/CTkButton_with_images.png b/documentation_images/CTkButton_with_images.png new file mode 100644 index 0000000..cf0dbad Binary files /dev/null and b/documentation_images/CTkButton_with_images.png differ diff --git a/simple_test_images.py b/simple_test_images.py new file mode 100644 index 0000000..4cb8e45 --- /dev/null +++ b/simple_test_images.py @@ -0,0 +1,33 @@ +import tkinter +import customtkinter # <- import the CustomTkinter module +from PIL import Image, ImageTk # <- import PIL for the images + +customtkinter.enable_macos_darkmode() +customtkinter.set_appearance_mode("System") # Other: "Dark", "Light" + +root_tk = tkinter.Tk() # create the Tk window like you normally do +root_tk.geometry("400x240") +root_tk.title("CustomTkinter Test") + +def button_function(): + print("button pressed") + +# load images as PhotoImage +settings_image = ImageTk.PhotoImage(Image.open("test_images/settings.png").resize((40, 40))) +bell_image = ImageTk.PhotoImage(Image.open("test_images/bell.png").resize((40, 40))) + +frame_1 = customtkinter.CTkFrame(master=root_tk, width=300, height=200, corner_radius=15) +frame_1.place(relx=0.5, rely=0.5, anchor=tkinter.CENTER) + +# button with settings-image +button_1 = customtkinter.CTkButton(master=frame_1, image=settings_image, width=60, height=60, + corner_radius=10, command=button_function) +button_1.place(relx=0.33, rely=0.5, anchor=tkinter.CENTER) + +# button with bell-image +button_2 = customtkinter.CTkButton(master=frame_1, image=bell_image, width=60, height=60, + corner_radius=10, command=button_function) +button_2.place(relx=0.66, rely=0.5, anchor=tkinter.CENTER) + +root_tk.mainloop() +customtkinter.disable_macos_darkmode() diff --git a/test_images/bell.png b/test_images/bell.png new file mode 100644 index 0000000..df3838f Binary files /dev/null and b/test_images/bell.png differ diff --git a/test_images/settings.png b/test_images/settings.png new file mode 100644 index 0000000..36e5d79 Binary files /dev/null and b/test_images/settings.png differ