I am writing a Simpsons trivia game as my first big programming project. My question is twofold:
Is this the right way to go about creating a background image? Keep in mind that my plan is to include the Simpsons theme song playing in the background as well as one or two buttons on top of the background image.
Assuming the code below is the right approach given what I want to accomplish, why am I getting a thin gray line on the left of my image and window? Ie. Why is the image not filling up the window perfectly like it is on the right side?
Here is my code:
from tkinter import *
from tkinter import ttk
from PIL import Image, ImageTk
root = Tk()
root.title("The Simpsons Trivia Game")
root.geometry('400x600')
root.resizable(0,0)
def resize_image(event):
new_width = event.width
new_height = event.height
image = copy_of_image.resize((new_width, new_height))
photo = ImageTk.PhotoImage(image)
label.config(image = photo)
label.image = photo
image = Image.open('E:\Simpsons Trivia Game\SimpsonsPic.png')
copy_of_image = image.copy()
photo = ImageTk.PhotoImage(image)
label = ttk.Label(root, image = photo)
label.bind('<Configure>', resize_image)
label.pack(fill=BOTH, expand = YES)
root.mainloop()
tkinter window with background image (left side of window not perfectly alligned with background image
I'm not sure I understand everything, but I managed to get rid of the border (at least on Linux) by doing:
from tkinter import *
from tkinter import ttk
from PIL import Image, ImageTk
root = Tk()
root.title("The Simpsons Trivia Game")
root.geometry("400x600")
root.resizable(0,0)
image = Image.open('/tmp/foobar.png')
photo = ImageTk.PhotoImage(image)
label = ttk.Label(root, image = photo)
label.pack()
label.place(relx=0.5, rely=0.5, anchor="center")
root.mainloop()
Related
I'm making a photo watermark programme using Python and Tkinter. Basically it allows the user to upload a photo and create a text watermark to put over the photo.
I'm working on a function so that the user can move the text watermark to wherever they want on the photo based on the x and y coordinates. Therefore, I'm trying to have the canvas be the same height and width as the photo so the user can easily play around with the watermark placement.
However, the canvas always seems to be bigger than the photo that gets uploaded and I'm not really sure why.
Here's the code I have so far, that takes the height and width of the photo and sets them as the size of the canvas. I've then halved them for the placement of the photo uploaded so that the photo is right in the middle of the canvas.
import tkinter
from tkinter import filedialog
from PIL import ImageTk
from tkinter import *
from PIL import Image
window = tkinter.Tk()
window.title("Image Watermarker")
window.config(padx=50, pady=10, bg='#ADD8E6', width=1000, height=1000)
# Choose photo to watermark, adds to window
upload = filedialog.askopenfilename(initialdir='/', title="Select an Image",
filetypes=(('png files', '*.png'), ('jpeg files', '*.jpeg')))
photo = ImageTk.PhotoImage(Image.open(upload))
h = photo.height()
w = photo.width()
canvas = Canvas(window, width=w, height=h, highlightthickness=0)
canvas.create_image((h / 2), (w / 2), image=photo, anchor=CENTER)
canvas.pack()
Change the line to:
canvas.create_image((w/2), (h/2), image=photo, anchor=CENTER)
as you just only swapped the order of width and height.
I'm making a hangman-like game; for that, I need all the different stages of the man to be visualized, hence images. I want the entire tkinter window to be an image, when I change the size it pushes the image right.
from tkinter import *
root=Tk()
root.geometry("600x350")
canvas = Canvas(root, width=1600, height=900)
canvas.pack()
img = PhotoImage(file="4.png")
canvas.create_image(470,190, image=img, )
root.mainloop()
If canvas is bigger than window then when you resize then it show more canvas but and it can looks like it moves image.
But if you use smaller canvas then pack() will try to keep centered horizontally. And if you add pack(expand=True) then it will try to keep it centered vertically.
In example code I added red background to window to show where is canvas
import tkinter as tk # PEP8: import *
root = tk.Tk()
root.geometry("600x350")
root['bg'] = 'red'
img = tk.PhotoImage(file="lenna.png")
canvas = tk.Canvas(root, width=600, height=350)
canvas.pack(expand=True)
canvas.create_image(300, 175, image=img)
root.mainloop()
Image Lenna from Wikipedia
PEP 8 -- Style Guide for Python Code
Before resizing:
After resizing:
If you want to draw only image then you could use Label(image=img)
import tkinter as tk # PEP8: import *
root = tk.Tk()
root.geometry("600x350")
root['bg'] = 'red'
img = tk.PhotoImage(file="lenna.png")
label = tk.Label(root, image=img)
label.pack(expand=True)
root.mainloop()
Before resizing:
After resizing:
BTW:
tkinter can bind() some function to event <Configure> and it will execute this function everytime when you resize window (and/or move window) - and this function may also move or resize image in window.
import tkinter as tk # PEP8: import *
from PIL import Image, ImageTk
def resize(event):
global img
lower = min(event.width, event.height)
#print(event.width, event.height, 'lower:', lower)
new_image = original_image.resize((lower, lower))
img = ImageTk.PhotoImage(new_image) # need to assign to global variable because there is bug in PhotoImage
label['image'] = img
# --- main ---
root = tk.Tk()
root.geometry("350x350")
root['bg'] = 'red'
original_image = Image.open("lenna.png")
img = ImageTk.PhotoImage(original_image)
label = tk.Label(root, image=img)
label.pack(expand=True)
root.bind('<Configure>', resize)
root.mainloop()
Before (it resized image at start to fit window):
After (it resized image to fit window):
I am trying to make a slideshow-like program using the tkinter module. Here is what I have done:
from tkinter import *
root = Tk()
photo = PhotoImage(file = "image.jpeg")
w = Label(root, image=photo)
w.pack()
def callback(event):
print ("clicked at", event.x, event.y)
##canvas= Canvas(root, width=800, height=500)
canvas= Canvas(root)
canvas.bind("<Button-1>", callback)
canvas.pack()
root.mainloop()
what's going on:
I am putting a picture on the canvas.
I am also detecting left clicks and getting the coordinates (which are printed on the shell)
But what really happens:
The picture (which needs to be in the same folder as the script, btw) appears on top, and a little blank space appears underneath, and I can click that (and get coordinates for the click). If I click the picture, nothing happens. When I click the blank space, it only gives the coordinates of the click for the blank space, not counting the picture as part of the area. If I enlarge the window, it just adds inert blank space on the sides, that do not react to being clicked.
My question is, how do I get the picture to be the clickable part (meaning, gets coordinates as well), and remove the blank space
If you can get the picture to enlarge with the window, that's even better.
Python 3.7.3, on MacBook. I only have the standard library.
You don't need the canvas and should bind on the label instead. Note that tkinter.PhotoImage() does not support JPEG image, use PNG or use Pillow module instead.
from tkinter import *
from PIL import ImageTk
root = Tk()
photo = ImageTk.PhotoImage(file="image.jpeg")
w = Label(root, image=photo)
w.pack()
def callback(event):
print ("clicked at", event.x, event.y)
w.bind("<Button-1>", callback)
root.mainloop()
You are not actually placing the image on the canvas. To place the image on the canvas use
.create_image(). To resize the image to the canvas. you can use resize method provided by the PIL library.
from tkinter import *
from PIL import ImageTk, Image
def resize_event(event):
resized = ImageTk.PhotoImage(img.resize((event.width, event.height), resample = Image.NEAREST))
canvas.itemconfig(img_item, image=resized)
canvas.moveto(img_item, 0, 0)
canvas.image = resized
def callback(event):
print ("clicked at", event.x, event.y)
root = Tk()
img = Image.open(r"Imagepath")
photo = ImageTk.PhotoImage(img)
#w = Label(root, image=photo)
#w.pack()
##canvas= Canvas(root, width=800, height=500)
canvas= Canvas(root)
img_item = canvas.create_image(0, 0, image = photo)
canvas.bind("<Button-1>", callback)
canvas.bind('<Configure>', resize_event)
canvas.pack(expand=True, fill='both')
root.mainloop()
hope you're all doing well. I've got a problem I hope you can help with.
I'm trying to build a board game in tkinter. This will have different shaped tiles being placed in squares on top of a background image. I have managed to add in the background with tk.PhotoImage and tk.Label, and correctly resized the image of the tile with ImageTk.PhotoImage.
However, when I place the tile on the board, all transparency is lost and replaced with monotone grey.
Minimal Code:
from PIL import Image,ImageTk
import tkinter as tk
def tile_push():
pass
# Create background image
root = tk.Tk()
root.geometry("390x500") # Size of background board
background_image = tk.PhotoImage(file="Gameboard.png")
background_label = tk.Label(root, image=background_image)
background_label.place(x=0, y=0, relwidth=1, relheight=1)
# Create button
im = Image.open("Chick.png").resize((100,100))
image_player_1 = ImageTk.PhotoImage(im)
b = tk.Button(root, image=image_player_1, command=tile_push, borderwidth=0, highlightthickness=0)
b.place(x=140, y=258, width=115, height=115)
tk.mainloop()
A similar question on SO shows how to set the background as black, but I need the background to be transparent.
Any help will be greatly appreciated!
Thanks for the support acw, I've managed to get it going now. This is what I did:
from PIL import Image,ImageTk
import tkinter as tk
def tile_push(*args, **kwargs):
print("It's alive!")
# Create background image
root = tk.Tk()
root.geometry("390x500") # Size of background board
canvas = tk.Canvas(root, width=390, height=500)
canvas.place(x=0,y=0)
background_image = tk.PhotoImage(file="Gameboard.png")
canvas.create_image((0,0), anchor="nw", image=background_image)
# Create button
im = Image.open("Chick.png").resize((115,115))
imTk = ImageTk.PhotoImage(im)
chick = canvas.create_image((140,258), anchor="nw", image=imTk)
canvas.tag_bind(chick, '<Button-1>', tile_push)
tk.mainloop()
I am trying to implement a button that has transparency using PIL and reading a PNG with transparency. I've followed all the tips I can find, but the button still shows up without transparency.
Screenshot of button in GIMP
Screenshot of Python output
Here is the code:
from Tkinter import *
from PIL import Image, ImageTk
root = Tk()
root.resizable(width=FALSE, height = FALSE)
global background, redbutton, rb1
rb1 =ImageTk.PhotoImage(file="test.png")
#confirm the png file is correct format
im = Image.open("test.png")
print im.mode
bg = PhotoImage(file = "background.gif")
GameWin = Canvas(root, bd = 2, height = 600, width = 450)
GameWin.create_image(0,0, image = bg, anchor = NW)
rb = Button(GameWin, bd=0, image=rb1)
# create a window in the canvas for the button
rb_win = GameWin.create_window(10, 10, anchor=NW, window=rb)
GameWin.pack()
root.mainloop()
Putting a window onto the canvas overwrites the background image. If I create_image in the canvas, I can correctly put the image of the button on the canvas (with transparency), but not an actual Button widget. My next step is to learn how to have the image react to mouseclicks so I can emulate some basic Button functionality.