Change background makes its labels disappear - python

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()

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

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

Canvas background image doesnt fit the entire window tkinter python

I'm new with tkinter GUI and trying to make a background to a top-level window by using canvas. I have tried to make the canvas the same size as the entire window by expand=TRUE.
However, it doesn't work well and the image is not sized as the window. can anyone help me fix that problem?
The top-level window is overviewWindow, which is in the function createOverviewWindow.
This is my code:
There is no output image because unfortunately I cant add images. The window I got has the background image in the top left corner but small sized
from tkinter import *
from tkinter import ttk, font, messagebox
from PIL import ImageTk, Image
import os
root = Tk()
root.title("Decoder of ultrasound images to detect colon tumors")
# Adding window icon
root.iconbitmap('afekaImage.ico')
rootWidth, rootHeight = 600, 600
screenWidth = root.winfo_screenwidth()
screenHeight = root.winfo_screenheight()
topLeftPosition = (screenWidth / 2 - rootWidth / 2, screenHeight / 2 - rootHeight / 2)
# Configure window size
root.geometry(f'{rootWidth}x{rootHeight}+{int(topLeftPosition[0])}+{int(topLeftPosition[1])}')
# open doc file
def openDocFile():
os.startfile("FinalProject.docx")
# adjusting background image to fit window
def adjustBackgroundImage(event):
label = event.widget
# avoid garbage collection option 1
# global resizedBackgroundImage, newBackgroundImage
# ----------
width = event.width
height = event.height
resizedBackgroundImage = copyImage.resize((width, height))
newBackgroundImage = ImageTk.PhotoImage(resizedBackgroundImage)
label.config(image=newBackgroundImage)
# avoid garbage collection option 2
label.image = newBackgroundImage
# ----------
def createUserManualWindow(button_userManual):
# global image1
userManualWindow = Toplevel(root)
userManualWindow.geometry(f'{rootWidth}x{rootHeight}+{int(topLeftPosition[0])}+{int(topLeftPosition[1])}')
userManualWindow.iconbitmap('afekaImage.ico')
image1 = ImageTk.PhotoImage(Image.open('background.jpg'))
label1 = ttk.Label(userManualWindow, image=image1)
label1.pack()
label1.bind('<Configure>', adjustBackgroundImage)
label1.pack(fill=BOTH, expand=YES)
def activateButtonUserManual():
button_userManual.configure(state="normal")
userManualWindow.destroy()
button_userManual.configure(state="disabled")
button_exit_userManualWindow = Button(userManualWindow, text="Exit", font=fontStyle,
command=lambda: [userManualWindow.destroy(), activateButtonUserManual()])
button_exit_userManualWindow.place(relx=0.4, rely=0.8, relwidth=0.2, relheight=0.1)
# will occurs only when esc pressed
userManualWindow.protocol("WM_DELETE_WINDOW", activateButtonUserManual)
# ----------
def createOverviewWindow(button_overview):
global image1, canvas
overviewWindow = Toplevel(root)
overviewWindow.geometry(f'{rootWidth}x{rootHeight}+{int(topLeftPosition[0])}+{int(topLeftPosition[1])}')
overviewWindow.iconbitmap('afekaImage.ico')
canvas = Canvas(overviewWindow, width=600, height=600)
canvas.pack(fill=BOTH, expand=TRUE)
image1 = ImageTk.PhotoImage(Image.open('background.jpg'))
canvas.create_image(0, 0, image=image1, anchor='nw')
image = Image.open('background.jpg')
copyImage = image.copy()
backgroundImage = ImageTk.PhotoImage(image)
label = ttk.Label(root, image=backgroundImage)
label.bind('<Configure>', adjustBackgroundImage)
label.pack(fill=BOTH, expand=YES)
fontStyle = font.Font(family="Segoe Script", size=10, weight=font.BOLD)
# Create buttons
button_userManual = Button(root, text="USER MANUAL", command=lambda: createUserManualWindow(button_userManual), font=fontStyle)
button_userManual.place(relx=0.4, rely=0.2, relwidth=0.2, relheight=0.1)
button_overview = Button(root, text="OVERVIEW", command=lambda: createOverviewWindow(button_overview), font=fontStyle)
button_overview.place(relx=0.4, rely=0.4, relwidth=0.2, relheight=0.1)
button_openDocFile = Button(root, text="DOC FILE", font=fontStyle, command=openDocFile)
button_openDocFile.place(relx=0.4, rely=0.6, relwidth=0.2, relheight=0.1)
button_quit = Button(root, text="Exit", font=fontStyle, command=root.destroy)
button_quit.place(relx=0.4, rely=0.8, relwidth=0.2, relheight=0.1)
root.mainloop()
The image you put was too big for the canvas. It's like putting a 8K image into a 720p monitor. It simply does not fit. So the solutions are
a) resize the image so it fits in the canvas (I see you have the PIL module so it should be quick)
b) Change the canvas size so it fits the image

Tkinter Canvas: Itemconfig failed update color

I've to change the color of the rectangle created with the Canvas item.
I've looked at other questions but I didn't find an answer to my problem.
I am recording a microphone using a USB Sound card. Once the record is started I want to put a RED light and, once it is finished, back it to green.
Here's the code:
main.py:
import tkinter as tk
from GUI import Demo1
def main():
root = tk.Tk()
app = Demo1(root)
root.mainloop()
if __name__ == '__main__':
main()
GUI.py:
class Demo1:
def __init__(self, master):
#Set geometry and title
self.master = master
self.master.title("DAQ - Sound Pressure Level")
self.master.geometry("480x320")
# Canvas zone
self.canvas = tk.Canvas(self.master,width=40,height=20,background='white')
self.canvas.grid(row=0,column=3)
self.frame = Frame(self.master)
self.frame.grid(row=0,column=3)
self.rect1 = self.canvas.create_rectangle(0,0,40,20, fill="green")
#canvas.bind(func=changecolor(canvas))
#set buttons
self.quitbutton = tk.Button(self.master, text = 'Quit', width = 10, command = self.close_windows)
self.quitbutton.grid(column=1,row=0)
self.startbutton = tk.Button(self.master, text = 'Start', width = 10, command = lambda: self.startacquisition())
self.startbutton.grid(column=0,row=0)
#self.zerobutton = tk.Button(self.master,text = 'Zero', width = 10, command = lambda: self.zerocalibration())
#self.zerobutton.grid(column=2,row=0)
#self.livebutton = tk.Button(self.master,text="Live/Stop", command=lambda: self.gui_handler, bg="red", fg="white")
#self.livebutton.grid(column=2,row=0)
def startacquisition(self):
chunk = 8192 # Record in chunks
print("Changing rect color to red")
self.canvas.itemconfig(self.rect1,fill='red')
p = pyaudio.PyAudio() # Create an interface to PortAudio
[....recording stuff...]
[...preparing plot...]
plt.show()
self.canvas.itemconfig(self.rect1,fill='green')
So when I press the START button it calls startacquisition(self) function. What happend is that the color doesn't upgrade until I close all the plot.
Why?
Thanks for your help.

Image in tkinter window by clicking on button

I need help about this program, this program should open image in new tkinter window by clicking on button, but it doesn't it just opens new window without image.
Where is the problem?
Using: python 3.3 and tkinter
This is program:
import sys
from tkinter import *
def button1():
novi = Toplevel()
canvas = Canvas(novi, width = 300, height = 200)
canvas.pack(expand = YES, fill = BOTH)
gif1 = PhotoImage(file = 'image.gif')
canvas.create_image(50, 10, visual = gif1, anchor = NW)
mGui = Tk()
button1 = Button(mGui,text ='Sklop',command = button1, height=5, width=20).pack()
mGui.mainloop()
create_image needs a image argument, not visual to use the image, so instead of visual = gif1, you need image = gif1. The next problem is that you need to store the gif1 reference somewhere or else it'll get garbage collected and tkinter won't be able to use it anymore.
So something like this:
import sys
from tkinter import * #or Tkinter if you're on Python2.7
def button1():
novi = Toplevel()
canvas = Canvas(novi, width = 300, height = 200)
canvas.pack(expand = YES, fill = BOTH)
gif1 = PhotoImage(file = 'image.gif')
#image not visual
canvas.create_image(50, 10, image = gif1, anchor = NW)
#assigned the gif1 to the canvas object
canvas.gif1 = gif1
mGui = Tk()
button1 = Button(mGui,text ='Sklop',command = button1, height=5, width=20).pack()
mGui.mainloop()
It's also probably not a good idea to name your Button the same name as the function button1, that'll just cause confusion later on.
from tkinter import *
root = Tk()
root.title("Creater window")
def Img():
r = Toplevel()
r.title("My image")
canvas = Canvas(r, height=600, width=600)
canvas.pack()
my_image = PhotoImage(file='C:\\Python34\\Lib\idlelib\\Icons\\Baba.gif', master= root)
canvas.create_image(0, 0, anchor=NW, image=my_image)
r.mainloop()
btn = Button(root, text = "Click Here to see creator Image", command = Img)
btn.grid(row = 0, column = 0)
root.mainloop()

Categories