How to use image as button in customtkinter? - python

at this code im trying to use image as button but its being created next to button
import customtkinter
from PIL import Image
customtkinter.set_appearance_mode("System") # Modes: "System" (standard), "Dark", "Light"
customtkinter.set_default_color_theme("blue") # Themes: "blue" (standard), "green", "dark-blue"
img = customtkinter.CTkImage(dark_image=Image.open(r"C:\Users\user\PycharmProjects\Customtkinter\images\img.png"))
class App(customtkinter.CTk):
def __init__(self):
super().__init__()
self.grid_columnconfigure(1, weight=1) # creating grid
self.grid_columnconfigure((2, 3), weight=0)
self.grid_rowconfigure((0, 1, 2), weight=1)
self.title("Main Screen") # creating main screen
self.geometry(f"{1100}x{580}")
self.button = customtkinter.CTkButton(master=self, image=img) #button (problem with img)
self.button.place(relx=0.5, rely=0.5)
if __name__ == "__main__":
app = App()
app.mainloop()
i were trying to import button from figma using tk designer, but buttons had another colours, and text was moved.
Also if it possible how to create gradient buttons using customtkinter?

Related

how to create a panedWindow in tkinter with three panedwindows as children and the left and right panedwindows having defined width

Please I am trying to create a UI but I coulld get the main window up and running. I want the left and right paned window to have defined width and the middle should cover remaining width. this is working for the left pane but it is not working for right pane. below is the code and the output. I am just learning tkinter and everything I read from the documentation does not work for me. PLease Is there anyone who could help.
`
import customtkinter
from tkinter import *
import tkinter.messagebox
customtkinter.set_appearance_mode("Dark") # Modes: "System" (standard), "Dark", "Light"
customtkinter.set_default_color_theme("dark-blue") # Themes: "blue" (standard), "green", "dark-blue"
def addPage():
pass
def copyText():
pass
class App(customtkinter.CTk):
width = 1440
height = 1024
def __init__(self):
super().__init__()
self.geometry(f"{App.width}x{App.height}")
self.radio_var = tkinter.IntVar(value=0)
###Menus
self.myMenu = Menu(self)
self.config(menu=self.myMenu)
# File Menu
self.fileMenu = Menu(self.myMenu)
self.myMenu.add_cascade(label="File", menu=self.fileMenu)
self.fileMenu.add_command(label="add...", command=addPage)
# Edit Menu
self.editMenu = Menu(self.myMenu)
self.myMenu.add_cascade(label="Edit", menu=self.editMenu)
self.editMenu.add_command(label="Copy", command=copyText)
# define Frames
self.grid_columnconfigure(0, weight=1)
self.grid_rowconfigure(0, weight=1)
self.frameBody = customtkinter.CTkFrame(master=self)
self.frameBody.grid(row=0, column=0, sticky="nswe")
self.frameFooter = customtkinter.CTkFrame(master=self, height=25, fg_color="#a6a6a6", corner_radius=0)
self.frameFooter.grid(row=1, column=0, sticky="nswe")
# main panel body
self.paneBody = PanedWindow(self.frameBody)
self.paneBody.pack(fill="both", expand=True)
#other three panes
self.paneLeftBody = PanedWindow(self.paneBody, bg = 'red', width = 300)
self.paneBody.add(self.paneLeftBody)
self.paneMiddleBody = PanedWindow(self.paneBody,orient = 'vertical')
self.paneBody.add(self.paneMiddleBody)
self.paneRightBody = PanedWindow(self.paneBody, bg = 'black', width = 300)
self.paneBody.add(self.paneRightBody)
self.middleTopPane = customtkinter.CTkFrame(self.paneMiddleBody, fg_color='red')
self.paneMiddleBody.add(self.middleTopPane,sticky="nswe")
self.middleBottomPane = customtkinter.CTkFrame(self.paneMiddleBody, height=300)
self.paneMiddleBody.add(self.middleBottomPane)
if __name__ == "__main__":
app = App()
app.mainloop()
`
Output

Custom tkinter label background

I am making a school project, and right now I'm having a problem with the label's backgrounds.
the objective is to make the label's background the same as the frame in both dark and light themes, and if possible, remove the little different color on the edges of the buttons.
import tkinter
import customtkinter
root_tk = customtkinter.CTk() # create CTk window like you do with the Tk window
root_tk.geometry("1280x720")
root_tk.minsize(1280, 720)
class GUI:
def __init__(self, root_tk):
Frame1 = customtkinter.CTkFrame(root_tk)
Frame1.pack
frame2 = customtkinter.CTkFrame(Frame1, width=100, height=720)
frame2.pack(pady=20,padx=20)
frame3 = customtkinter.CTkFrame(root_tk, width=250, height=725)
frame3.pack()
frame3.place(anchor="w", relx=0.0, rely=0.5, relwidth=0.2, relheight=1)
self.test()
def test(self):
self.switch = customtkinter.CTkSwitch(master=root_tk, text="Dark Mode", command=self.theme_change)
self.switch.toggle(1)
self.switch.place(relx=0.05, rely=0.05)
self.label_width = customtkinter.CTkLabel(root_tk, text="glasses width:")
self.label_width.place(relx=0.1, rely=0.67, anchor=tkinter.CENTER)
self.label_height = customtkinter.CTkLabel(root_tk, text="glasses height:")
self.label_height.place(relx=0.1, rely=0.77, anchor=tkinter.CENTER)
self.button_add_Face = customtkinter.CTkButton(root_tk, width=200, height=50, border_width=0, corner_radius=8, hover=True, text="Adicionar Rostos", command=print("added"))
self.button_add_Face.place(relx=0.1, rely=0.6, anchor=tkinter.CENTER)
def theme_change(self):
if self.switch.get() == 1:
customtkinter.set_appearance_mode("dark")
else:
customtkinter.set_appearance_mode("light")
start = GUI(root_tk)
root_tk.mainloop()
According to the source code of the CTkBaseClass for the widgets. The background color should be the same as the fg_color of your master as long as you haven't defined explicitly a bg_color for your widget.
Look at the configure method of the BaseClass and follow it to the detect_color_of_master.
the objective is to make the label's background the same as the frame
in both dark and light themes
So this should do the trick:
Frame1 = customtkinter.CTkFrame(root_tk,fg_color=root_tk.fg_color)
Frame1.pack()
self.button_add_Face = customtkinter.CTkButton(Frame1, width=200, height=50, border_width=0, corner_radius=8, hover=True, text="Adicionar Rostos", command=print("added"), border_color=root_tk.fg_color)
But you may are more interested in the ThemeManager. There are some Themes and you could just do another .json file in the form of the examples and add it in this directory to apply your own style.

How do you get a second canvas to appear on a tkinter Toplevel window when inside a class?

I'm using Tkinter to create an application, and with this Dashboard class, I'm trying to get a pop out window to show another canvas, so I can use create_image and tag_bind on the pop out. The result I'm currently getting is that the second canvas appears over the first canvas instead of in the pop out window.
import tkinter as tk
from tkinter import *
class Dashboard(tk.Tk):
"""
Configures, and displays the Dashboard
"""
def __init__(self):
tk.Tk.__init__(self)
self.config(width=1440, height=1024)
canvas = tk.Canvas(self, bg="#343333", height=1024, width=1440, bd=0, highlightthickness=0, relief="ridge")
canvas.place(x=0, y=0)
# Captures the background image for the canvas
image_path = "dashboard_background.png"
self.background_img = tk.PhotoImage(file=image_path)
canvas.create_image(0, 0, anchor='nw', image=self.background_img)
def logoutbuttonClicker():
pop = Toplevel(self)
pop.geometry('537x273')
pop.config(height=273, width=537)
logout_canvas = tk.Canvas(canvas, bg="#ffffff", height=273, width=537, bd=0, highlightthickness=0, relief="ridge")
logout_canvas.place(x=0, y=0)
self.logout_background_img = PhotoImage(file=f"logout_background.png")
logout_canvas.create_image(268.5, 136.5, anchor='nw', image=self.logout_background_img)
self.logout_yes_img = PhotoImage(file=f"logout_yes.png")
self.logout_no_img = PhotoImage(file=f"logout_no.png")
logout_image_path = "dashboard_logout.png"
self.logout_image = tk.PhotoImage(file=logout_image_path)
logoutButton = canvas.create_image(45, 950, anchor='nw', image=self.logout_image)
canvas.tag_bind(logoutButton, "<ButtonRelease-1>", lambda event: logoutbuttonClicker())
def main():
app = Dashboard()
app.mainloop()
if __name__ == '__main__':
main()
This is how it currently appears in the UI

Label text isn't appearing in tkinter Frame

I've been researching this question, but none of the solutions I've found seem to work. I'm trying to get a Label (self.status_bar in the code below) to appear in my frame, but any edits (i.e. using update() method or resizing the frame/text widget/window) I've made have gotten me nowhere.
from tkinter import *
from tkinter import filedialog
from tkinter import font
#Build frame with features to put into parent window
class TextEditor:
def __init__(self, master):
self.master = master
self.frame = tk.Frame(self.master)
#Create Scrollbar
self.text_scroll = tk.Scrollbar(self.frame)
self.text_scroll.pack(side=RIGHT, fill=Y)
#Create text box
self.text = tk.Text(self.frame, width=155, height=55, font=('Helvetica', 12), selectbackground="yellow",
selectforeground = "black", undo=True, yscrollcommand=self.text_scroll.set)
self.text.pack()
#Configure scrollbar
self.text_scroll.config(command=self.text.yview)
#Create menu
self.menu = tk.Menu(self.master)
self.master.config(menu=self.menu)
#Add file menu
self.file_menu = tk.Menu(self.menu, tearoff=False)
self.menu.add_cascade(label="File", menu=self.file_menu)
self.file_menu.add_command(label="Open")
self.file_menu.add_command(label="Save")
self.file_menu.add_command(label="New")
self.file_menu.add_separator()
self.file_menu.add_command(label="Exit", command=self.master.destroy)
#Add edit menu
self.edit_menu = tk.Menu(self.menu, tearoff=False)
self.menu.add_cascade(label="Edit", menu=self.edit_menu)
self.edit_menu.add_command(label="Cut")
self.edit_menu.add_command(label="Copy")
self.edit_menu.add_command(label="Undo")
self.edit_menu.add_command(label="Redo")
#Add status bar to bottom of app
self.status_bar = tk.Label(self.frame, text="Ready", anchor=E)
self.status_bar.pack(fill=X, side=BOTTOM, ipady=5)
#Pack frame into window
self.frame.pack()
#Instantiates the text editor app
def main():
root = tk.Tk()
app = TextEditor(root)
root.geometry("1220x660")
root.title("Text Editor")
root.mainloop()
if __name__ == '__main__':
main()
You are forcing the window to a size that is too small to fit all of the widgets. When you do that while using pack, pack will start to shrink widgets in order to make them fit, starting with the last widget that was packed. In this case that's the status bar. So, pack starts removing pixels from self.status_bar until there's enough room for the other widgets. Eventually, it has to completely remove the status bar, and then start shrinking the text widget.
The first step is to create the status bar first, so that the text widget is higher in the stacking order (ie: pack will try to shrink it before shrinking other widgets).
The second thing you should do is use the appropriate options to get the TextEditor window to fill the frame, and get the frame to fill the window. For example:
self.text.pack(fill="both", expand=True)
self.frame.pack(fill="both", expand=True)
I suggest, with the more complicated layout you have, that you use the grid method instead of pack. Here is the code with the widgets gridded instead of packed:
import tkinter as tk
from tkinter import filedialog
from tkinter import font
from tkinter.constants import *
#Build frame with features to put into parent window
class TextEditor:
def __init__(self, master):
self.master = master
self.frame = tk.Frame(self.master)
#Create Scrollbar
self.text_scroll = tk.Scrollbar(self.frame)
self.text_scroll.grid(row=0, column=1, sticky=E+NS) ### EDITED THIS LINE
#Create text box
self.text = tk.Text(self.frame, font=('Helvetica', 12), selectbackground="yellow", ### EDITED THIS LINE
selectforeground = "black", undo=True, yscrollcommand=self.text_scroll.set)
self.text.grid(row=0, column=0, sticky=NSEW) ### EDITED THIS LINE
#Configure scrollbar
self.text_scroll.config(command=self.text.yview)
#Create menu
self.menu = tk.Menu(self.master)
self.master.config(menu=self.menu)
#Add file menu
self.file_menu = tk.Menu(self.menu, tearoff=False)
self.menu.add_cascade(label="File", menu=self.file_menu)
self.file_menu.add_command(label="Open")
self.file_menu.add_command(label="Save")
self.file_menu.add_command(label="New")
self.file_menu.add_separator()
self.file_menu.add_command(label="Exit", command=self.master.destroy)
#Add edit menu
self.edit_menu = tk.Menu(self.menu, tearoff=False)
self.menu.add_cascade(label="Edit", menu=self.edit_menu)
self.edit_menu.add_command(label="Cut")
self.edit_menu.add_command(label="Copy")
self.edit_menu.add_command(label="Undo")
self.edit_menu.add_command(label="Redo")
#Add status bar to bottom of app
self.status_bar = tk.Label(self.frame, text="Ready", anchor=E)
self.status_bar.grid(row=1, column=0, sticky=S+EW) ### EDITED THIS LINE
# Configure the rows and columns so that they expand properly ### ADDED THESE LINES
self.frame.rowconfigure(0, weight=1) ### ADDED THESE LINES
self.frame.columnconfigure(0, weight=1) ### ADDED THESE LINES
#Pack frame into window
self.frame.pack(expand=YES, fill=BOTH) ### EDITED THIS LINE
#Instantiates the text editor app
def main():
root = tk.Tk()
app = TextEditor(root)
root.geometry("1220x660")
root.title("Text Editor")
root.mainloop()
if __name__ == '__main__':
main()
Notice how I also changed the line where the frame is packed into the window. The only thing keeping the frame filling the window before was the size of the text widget.
With these changes, the widgets expand properly, so I also removed the width and height parameters from the creation of self.text.

Change background makes its labels disappear

I want to build an app where you can change the background image by clicking a button. First, to put a background to my frame, I created the image as a label and then sub-classed every other label to the background label. Now when you click the button "Change Background", it changes the background. However, all the labels disappear. Buttons only appear when you hover over them by the cursor. Labels never appear!
My questions are:
Why does this happen?
How to fix it?
Here is a simple code to reproduce the issue:
import tkinter as tk
from PIL import ImageTk, Image
class App():
def __init__(self, root):
self.root = root
self.controlFrame = tk.Frame(root, width=900, height=600)
self.controlFrame.pack_propagate(0) # Prevents resizing
self.controlFrame.pack()
img = Image.open('images/outside.jpg').resize((900, 600))
self.background_image = ImageTk.PhotoImage(img)
self.background_label = tk.Label(self.controlFrame, image=self.background_image)
self.background_label.configure(image = self.background_image)
self.background_label.pack(fill="both", expand="yes")
self.changeButton = tk.Button(self.background_label, text="Change Background",
command = self.changeBK)
self.changeButton.place(x=400, y=300)
self.someButton = tk.Button(self.background_label, text="Some Button")
self.someButton.place(x=400, y=100)
self.someOtherButton = tk.Button(self.background_label, text="Some Other Button")
self.someOtherButton.place(x=400, y=450)
self.userMessage = tk.Label(self.background_label, text="Label", height = 3 , width= 14, bg="white")
self.userMessage.place(x=400, y= 200)
def changeBK(self):
img = Image.open('images/muddyPath.jpg').resize((900, 600))
self.background_image = ImageTk.PhotoImage(img)
self.background_label.configure(image = self.background_image)
def main():
win = tk.Tk() # Create a window
win.title("Using Multiple Layouts") # Set window title
win.geometry("900x600") # Set window size
win.resizable(False, False) # Both x and y dimensions ...
# Create the GUI as a Frame
# and attach it to the window ...
myApp = App(win)
# Call the GUI mainloop ...
win.mainloop()
if __name__ == "__main__":
main()

Categories