Is there any way to import an image into python using PIL and set it as the background for a ttk mainframe that spans the entirety of a Tkinter root window? As of now I have only seen ways to do this is a Tkinter root. Also is there any way to make ttk self adjust the size of the image so that even if it's small it covers the entire screen?
So to sum up I want an image to cover the entire ttk mainframe box without messing with me putting anything else in the ttk frame.
for example
if the pic covered the entire window, a command,
ttk.Button(root, text="Hello").grid(column=0, row=0, sticky=(N,S,W,E))
would still insert a button in the mainframe. Thanks :)
You can't set an image background to a ttk frame, they don't accept image options. So you could make a ttk frame and put a label or something inside it and then have it span the frame adapting the below example.
Here's a small example demonstrating what you want. We load an image with pil, notice the image linked will be smaller (I hope) than your screensize.
So, we set the geometry of the root window to be the entire screen the image is less than this so we resize it to cover the entire width. You can override the max and min height and then set it according to this. Just a sample value. We then place the bg label and grid widgets on top of it. The label has a lower stacking order than the other widgets you will place with grid so they appear on top. Alternatively you could use a canvas, or another widget. With a canvas you'll have to use create_window to place widgets in the canvas.
import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
root = tk.Tk()
width, height = root.winfo_screenwidth(), root.winfo_screenheight()
#print(root.winfo_screenheight(), root.winfo_screenwidth())
root.geometry("%dx%d" % (width, height))
#URL FOR BACKGROUND
#https://www.google.com/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&ved=0ahUKEwiVroCiyZHMAhXKeT4KHQHpDVAQjBwIBA&url=http%3A%2F%2Fwallpaperswide.com%2Fdownload%2Fblack_background_metal_hole_very_small-wallpaper-800x480.jpg&psig=AFQjCNEjZ7GDbjG9sFie-yXW3fP85_p0VQ&ust=1460840934258935
image = Image.open("background.jpg")
if image.size != (width, height):
image = image.resize((width, height), Image.ANTIALIAS)
#print("DONE RESIZING")
# image.save("background.jpg")
#print(image.size)
image = ImageTk.PhotoImage(image)
bg_label = tk.Label(root, image = image)
bg_label.place(x=0, y=0, relwidth=1, relheight=1)
bg_label.image = image
your_button = ttk.Button(root, text='This is a button')
your_button.grid()
root.mainloop()
Related
My image "1_T.png" has a transparent background. I want to bring it to the front of my tkinter window.
I first tried inserting the image in a label. This brought the image to the front of the window but the transparent background was lost because labels can't have transparent backgrounds is my understanding.
I then tried using canvas.create_image(). This helped me preserve the transparent background of my image "1_T.png" but i can't work out how to bring it to the front. I tried canvas.tag_raise(). But that didn't work either.
For example, in the code below, i want to bring the image in front of the label.
Is there a way for me to do that?
import tkinter as tk
HEIGHT = 500
WIDTH = 1000
root = tk.Tk()
canvas = tk.Canvas(root, bg='black', height=HEIGHT, width=WIDTH)
canvas.pack()
mylabel = tk.Label(root, text='testing', bg='#00FFFF')
mylabel.place(relx=0, rely=0, relwidth=0.3, relheight=0.1)
myimage = tk.PhotoImage(file='1_T.png')
myimage2 = canvas.create_image(0, 0, image=myimage)
canvas.tag_raise(myimage2)
root.mainloop()
I'm trying to open image files and display them in python 3.8 using Tkinter and Pillow, but something is scaling the images wrong on my screen.
import tkinter as tk
from PIL import Image, ImageTk
class ViewingWindow(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.image = None
self.canvas = tk.Canvas(self, width=500, height=500)
self.canvas.pack()
def setImage(self, img):
self.image = img
print(img.width())
print(img.height())
print(self.canvas["width"])
print(self.canvas["height"])
self.canvas.create_image(0, 0, anchor=tk.NW, image=img)
window = tk.Tk()
canvas = ViewingWindow(window)
canvas.pack()
img = Image.open("500x500.jpg")
img = ImageTk.PhotoImage(img)
canvas.setImage(img)
window.mainloop()
This is the result, shown for reference is Windows image viewer at "show actual size", and Gimp at scaling=100%:
The 4 print statements all show "500", every part of the system seems to agree that the image is shown at 500x500, except the actual pixels on the screen. For whatever reason it's scaled to something close to 750x750, what in the world is scaling my image? This is consistent for all images I've tried to open in Tkinter, and regardless on window size and widget sizes.
Tested on Windows 10 with screen resolution 1920x1080.
it's scaled to something close to 750x750
750/500 = 150%.It seems that your system zoom ratio is 150%.
To show the right image size.Just like furas said,you need to use DPI awareness.Read the problem in MSDN official doc
About DPI awareness.
To solve the problem,you can set the DPI awareness in your code.(Or you can change the zoom ratio to 100%)
In my PC,the are not the same size without DPI awareness.Now after set the DPI awareness:
Add this in your code:
import ctypes
ctypes.windll.shcore.SetProcessDpiAwareness(2) # this could only be used when your version of windows >= 8.1
So I have 2 images, 1 image is supposed to be the background and the other 1 is just an image of a character.
I am able to put one image over the other but the image has white borders even though it's a PNG file.
This is how it looks like:
This is how I want it to look like:
Here are the two separte images:
https://imgur.com/a/SmE5lgC
Sorry that I didnt post the images directly but I can not since I do no have 10 reputation points.
I've tried converting it to RGBA but same thing happened.
from tkinter import *
from PIL import Image
root = Tk()
root.title("Game")
background = PhotoImage(file="back.png")
backgroundlabel = Label(root, image=background)
backgroundlabel.pack()
character = PhotoImage(file="hero.png")
characterlabel = Label(root, image=character)
characterlabel.place(x=0,y=0)
root.mainloop()
You just need to use the canvas widget in Tkinter. Only the canvas widget supports transparency. This has to do with how Tkinter draws the display. As of right now, your code is just overlaying two images. Tkinter does not know how to compose them with transparency unless you use the canvas widget.
See the following code:
from tkinter import *
from PIL import Image
root = Tk()
root.title("Game")
frame = Frame(root)
frame.pack()
canvas = Canvas(frame, bg="black", width=700, height=400)
canvas.pack()
background = PhotoImage(file="background.png")
canvas.create_image(350,200,image=background)
character = PhotoImage(file="hero.png")
canvas.create_image(30,30,image=character)
root.mainloop()
All I did was download the images you provided. I did not modify the images. So, the bottom line is that you just need to use the canvas widget.
VoilĂ !
Note: The question asked is a duplicate of How do I make Tkinter support PNG transparency?
I found this code:
from PIL import Image, ImageTk
import tkinter as tk
root = tk.Tk()
img = Image.open(r"Sample.jpg")
canvas = tk.Canvas(root, width=500, height=500)
canvas.pack()
tk_img = ImageTk.PhotoImage(img)
canvas.create_image(250, 250, image=tk_img)
root.mainloop()
It displays any picture in 500x500px resolution. I tried to change it and display it in its original size:
from PIL import Image, ImageTk
import tkinter as tk
root = tk.Tk()
img = Image.open(r"D:/1.jpg")
canvas = tk.Canvas(root, width=img.width, height=img.height)
canvas.pack()
tk_img = ImageTk.PhotoImage(img)
canvas.create_image(img.width/2, img.height/2, image=tk_img)
root.mainloop()
But something went wrong and the picture with a size of 604x604px shows in a window with a size of 602x602px, but the window size is correct.
Take a look (full image).
What am I doing wrong?
P.S. Sorry for bad English.
Well, no, your first example still cuts off by a few pixels. All top level windows will have padding around their absolute borders to prevent other elements from 'bleeding' into the borders and looking unprofessional.
You are still being given a canvas of 604 pixels by 604 pixels, but the root window itself is asserting its padding. I could not find any way of removing this top level padding, and it may very well appear differently in other operating systems. A work-around could be to request a canvas size that is slightly larger than the image you would like to display.
Another issue, if you're aiming for precision, would be the line...
canvas.create_image(img.width/2, img.height/2, image=tk_img)
Which could create off-by-one errors if your width or height is an odd number. You can anchor images to the north-west corner and place them at the co-ordinates (0, 0) like such:
canvas.create_image(0, 0, anchor=tk.NW, image=tk_img)
button, label etc over an background image using tkinter. few days before I just stared learning python so I am sorry if this question look silly.. my code is below.. but at this moment label is showing below image not over image..please correct me.
import tkinter
haren = tkinter.Tk()
width, height = haren.winfo_screenwidth(), haren.winfo_screenheight()
bg = tkinter.PhotoImage(file="img/bg.png")
panel1 = tkinter.Label(haren, image=bg)
panel1.pack(side='top', fill='both', expand='yes')
haren.wm_title("Hi Sana")
haren.grid()
yeah=tkinter.Label(haren, text="Developed by Full Mad Haren Sarma")
yeah.pack()
haren.wm_geometry("%dx%d+0+0" % (width, height))
haren.mainloop()
In your current code, if you want both the image and the text to be visible, the window must be big enough for both. If the background image is exactly as large as your screen size, the text will be hidden. You can reveal the text by increasing the window size (I recommend testing with a smaller image), noting that it collapses under the image when you shrink the window.
Try changing your geometry manager to grid instead of pack.
panel1.pack(side='top', fill='both', expand='yes')
changes to:
panel1.grid(row=0, column=0)
and
yeah.pack()
changes to:
yeah.grid(row=0, column=0, sticky='s')
Note how both widgets are added to the same row and column, so the most recently-grid()ed widget will appear on top of previous ones. The sticky option indicates where in its grid square the widget will rest (the south end in this case).