Set a background image for my window - python-3.x

I just wondering what I should do to apply an image as background of my tkinter window.
I want this window with a gif image in the background and a few buttons on top of it..
the error msg says: "x.image = bg_image.grid(row = 0, column = 0)
AttributeError: 'PhotoImage' object has no attribute 'grid'"
do I need to import something else?
whats wrong? I dont even know if this PhotoImage code is supported by this version of python (python 3.1.1)...
from tkinter import*
window = Tk()
window.title("ksdasndsnadn")
bg_image = PhotoImage(file ="pic.gif")
x = Label (image = bg_image)
x.image = bg_image.grid(row = 0, column = 0)
window.geometry("600x300")
app = Application(window)
window.mainloop()

You need to apply the grid method to the label that contains the image, not the image object:
bg_image = PhotoImage(file ="pic.gif")
x = Label (image = bg_image)
x.grid(row = 0, column = 0)
http://effbot.org/tkinterbook/photoimage.htm

Related

I am having trouble putting a menu bar above a Canvas widgit using tkinter

I am trying to add a menu bar on a Canvas widget. I am currently testing it using some demo code I found online, before I implement it in an application that I am writing. Currently the code shows the window, but the Menu bar appears at the bottom of the page, instead of the top.
Also more of a side note: Is there a way that I can use a function in a seperate python file to draw a shape without having it create an entire new window?
my code:
import tkinter
from tkinter import *
from tkinter import messagebox
def option():
print("Options")
top = Tk()
mb = Menubutton(top, text = "condiments", relief = RAISED)
C = Canvas(top, bg = "blue", height = 250, width = 250)
C.grid()
mb.grid()
mb.menu = Menu(mb, tearoff = 0)
mb["menu"] = mb.menu
mb.menu.add_command(label = "mayo", command = option)
mb.menu.add_command(label = "ketchup", command = option)
coord = 10,50.240, 210
coord1 = 10,50,20,60
arc = C.create_arc(coord, start = 0, extent = 150, fill = "red")
line = C.create_line(coord, fill = "white")
oval = C.create_oval(coord1, fill = "black")
top.mainloop()
By default, grid will automatically increase the row and column unless you specify otherwise. You could also simply reorder the code so that the defaults match up with your expectation.
The Zen of Python says that "explicit is better than implicit". If you explicitly define the row and column, the code will be easier to understand and you can put the menubar wherever you want.
mb.grid(row=0, column=0)
C.grid(row=1, column=0)

I want to display image dynamically in Tkinter using Pillow

I want to be able to display photos dynamically in Tkinter I have one button that will find the paths to the photos I want to display and as I add photos I want them to be displayed at the top of the canvas
I have already tried going through a for loop of the array after I upload the photos but that doesn't seem to do what I want, and now I am trying to iterate with a while loop but that doesn't work. I am kind of at a loss now. Below is my code
import tkinter as tk
from tkinter import filedialog as tkfd
from PIL import ImageTk, Image
import time
photo_name_list = []
def find_photos():
photo = tkfd.askopenfile()
photo_name_list.append(photo.name)
window = tk.Tk()
#creates the canvas
canvas = tk.Canvas(window, width = WINDOW_WIDTH,
height = WINDOW_HEIGHT, bg="green")
canvas.pack()
b1 = tk.Button(canvas, text="Click me to add 5 photos of yourself",
height = 5, width = 30, command = find_photos)
canvas.create_window(WINDOW_WIDTH//3, WINDOW_HEIGHT//3, window = b1)
while True:
if len(photo_name_list) > 0:
for image in photo_name_list:
img = Image.open(image)
tkimage = ImageTk.PhotoImage(img)
tk.Label(window, image=tkimage).pack()
canvas.update()
time.sleep(1/60)
window.mainloop()
So as you can see in the code I have one button that does that takes the path to an image as a string and appends it to the list. I want to display photos as they are appended.
This should work
import tkinter as tk
from tkinter import filedialog as tkfd
from PIL import ImageTk, Image
import time
WINDOW_WIDTH = 500
WINDOW_HEIGHT = 500
phat_list = []
images_reference_list = []
def find_photos():
photo = tkfd.askopenfile()
file_path = photo.name
img = Image.open(file_path)
photo_image = ImageTk.PhotoImage(img)
tk.Label(window, image=photo_image).pack(side=tk.TOP)
images_reference_list.append(photo_image)
phat_list.append(file_path)
window = tk.Tk()
#creates the canvas
canvas = tk.Canvas(window, width = WINDOW_WIDTH,
height = WINDOW_HEIGHT, bg="green")
canvas.pack(side=tk.BOTTOM)
b1 = tk.Button(canvas, text="Click me to add 5 photos of yourself",
height = 5, width = 30, command = find_photos)
canvas.create_window(WINDOW_WIDTH//3, WINDOW_HEIGHT//3, window = b1)
window.mainloop()
I've added the code lines that display the photo inside the function find_photos().
The while statement was causing some troubles i assume, you have always to check if the while will ever end for have a working code
and if you want to display an image you have always to keep a solid reference of it , the best way is to add it into a list

TKinter Frame Not Filling in TopWindow

I'm encountering a problem. I have a root window(main window) in my code, but right now I'm creating a toplevel window for the root. I want to put a frame within a toplevel window. My problem is that I can't make the frame to fill the whole window. It only acts as a background where the widgets are placed.
def booksAvailableOpen():
## Creates a new window with all available books
global books
global backButton
books = Toplevel(root)
books.title("Available books")
books.lift(root)
books.geometry("+400+300")
books.geometry("400x400")
## Frame for toplevel window
booksFrame = ttk.Frame(books, height = 600, width = 600, relief = SUNKEN)
booksFrame.grid(row = 0, column = 0)
testLabel = ttk.Label(booksFrame,text = 'hui')
testLabel.grid(row = 0, column = 1)
## Back button used to destroy window
backButton = ttk.Button(booksFrame,text = "Go back", command = booksAvailableBackButton)
backButton.grid(row = 1, column = 1)
I also can't colour the frames, which is another issue I'm experiencing

size of a background image in tkinter

I need to resize my window(tkinter) according to the width and height of my background image.
My code
from tkinter import *
from PIL import ImageTk
import cv2
image=cv2.imread("New_refImg.png")
width_1, height_1,channels = image.shape
canvas = Canvas(width = width_1, height = height_1, bg = 'blue')
canvas.pack(expand = YES, fill = BOTH)
img = ImageTk.PhotoImage(file = "New_refImg.png")
canvas.create_image(10, 10, image = img, anchor = NW)
mainloop()
I'm using a simple method, I call the same image twice : image=cv2.imread("New_refImg.png") and img = ImageTk.PhotoImage(file = "New_refImg.png") but is there a way change this line img = ImageTk.PhotoImage(file = "New_refImg.png") to something like that img = ImageTk.PhotoImage(image) (image already has been called in the 3rd line of the code)
Thank you
I don't know about PIL, but I can show you how to do it in tkinter:
from tkinter import *
root = Tk() # Create Tk before you can create an image
img = PhotoImage(file='pilner.png')
w, h = img.width(), img.height()
canvas = Canvas(root, width=w, height=h, bg='blue', highlightthickness=0)
canvas.pack(expand = YES, fill = BOTH)
canvas.create_image(0, 0, image=img, anchor=NW)
root.mainloop()
highlightthickness=0 rmoves the highlight border on the canvas. I'm positioning it at 0,0 so as to not show the bg.

PNG image that support scaling and changing transparency in python

I want to show PNG picture on canvas.
Before it I need to resize it and change transparency.
I found that I can load image and change alpha channel with PhotoImage like this:
image1 = PIL.Image.open('aqua.png')
image1.putalpha(128)
gif1 = ImageTk.PhotoImage(image1)
Also I can load PhotoImage and resize it like this:
gif1 = PhotoImage(file = 'aqua.png')
gif1 = gif1.subsample(5)
But I can't perform both this things on same PhotoImage
I understand that PhotoImage and ImageTk.PhotoImage are different classes in my code.
>> print (ImageTk.PhotoImage)
<class 'PIL.ImageTk.PhotoImage'>
>> print (PhotoImage)
<class 'tkinter.PhotoImage'>
I tried to found functionality that I need in both classes but without success.
Maybe I need perform subsample and than convert my tkinter.PhotoImage to PIL.ImageTk.PhotoImage and then perform putalpha but it sounds weird.
Please refer me to right direction about png cooking in Python.
Here is all my code:
from tkinter import *
import PIL
from PIL import Image, ImageTk
canvas = Canvas(width = 200, height = 200)
canvas.pack(expand = YES, fill = BOTH)
image1 = PIL.Image.open('aqua.png')
image1.putalpha(128)
gif1 = ImageTk.PhotoImage(image1)
# gif1 = PhotoImage(file = 'aqua.png')
# next line will not work in my case
gif1 = gif1.subsample(5)
canvas.create_image(0, 0, image = gif1, anchor = NW)
mainloop()
You can use the resize method included in the Image class. Here is the modified code:
from tkinter import *
from PIL import Image, ImageTk
canvas = Canvas(width = 200, height = 200)
canvas.pack(expand = YES, fill = BOTH)
image1 = Image.open('aqua.png')
image1.putalpha(128)
image1 = image1.resize((image1.width//5,image1.height//5))
gif1 = ImageTk.PhotoImage(image1)
canvas.create_image(0, 0, image = gif1, anchor = NW)
mainloop()

Resources