I started to learn Python one month ago. Sorry if my question is not good, this is my first question here.
I have made a small game using tkinter, but I have a problem.
I made a big label with a picture on it as background. Whenever I make more labels with text on them, the text will have gray background. However what I want is for every text to have the picture that I already placed as background.
Here's some code to explain it:
from tkinter import*
x=Tk()
x.geometry("1000x1000")
z=PhotoImage(file="D:\\Blue.gif")
v=Label(x,text="hi",font=100,fg="red",compound=CENTER,image=z,width=1000,height=1000)
v.place(x=0,y=0)
v1=Label(x,text="OO",font=100,fg="red")
v1.place(x=300,y=400)
x.mainloop()
The v label works very well as long as I use compound with it. It shows the picture with the text "hi" on it.
However I want the v1 label to have the same background as v, instead of gray background.
All widgets have background - they can't be transparent.
You can use tk.Canvas to put text without background on image or transparent image on text.
effbot.org: Canvas, PhotoImage
#!/usr/bin/env python3
import tkinter as tk
from PIL import Image, ImageTk
# --- constants ---
WIDTH = 800
HEIGHT = 600
# --- main ---
root = tk.Tk()
c = tk.Canvas(root, width=WIDTH, height=HEIGHT)
c.pack()
# only GIF and PGM/PPM
#photo = tk.PhotoImage(file='test.gif')
# other formats
image = Image.open('test_transparent.png')
photo = ImageTk.PhotoImage(image)
# use in functions - solution for "garbage collector" problem
c.image = photo
i = c.create_image((WIDTH//2, HEIGHT//2), image=photo)
t = c.create_text((WIDTH//2, HEIGHT//2), text='Hello World')
root.mainloop()
Change order and you get image on text
t = c.create_text((WIDTH//2, HEIGHT//2), text='Hello World')
i = c.create_image((WIDTH//2, HEIGHT//2), image=photo)
test_transparent.png (image with transparent background)
Related
it's my first question here.
I use tkinter with python3.9 for displaying an image, a flag of which country it shows up on the window
# gets the img flag
flag = PhotoImage(file=flagsFolder+countryList[rand_label]) # the path is "D:\Images\Flags of the world" + "XXXX.gif"
# creates the img Label
flagLabel = Label(frame, image=flag)
flagLabel.place(x=window_width/2, y=200, anchor='center')
So, when I try to display the image, it shows me this:
A flag should be here instead of the white image.
Why isn't it showing up?
So I messed around a bit and found out a solution.
I had to use ImageTk from Pillow so:
from PIL import ImageTk
Then, instead of creating a Label for my image, I made a Canvas:
# notice how I used ImageTk.PhotoImage instead of the basic PhotoImage from Tkinter
img = ImageTk.PhotoImage(file='filename.png')
# creates the img Canvas
imgCanvas = Canvas(frame)
imgCanvas.place(x=window_width/2, y=200, anchor='center', width=img.width(), height=img.height())
imgCanvas.create_image(0, 0, anchor=NW, image=img)
imgCanvas.image = img # now the image displays perfectly :D
The final result:
Im using python 2.7 to build a satellite tracker for a cubesat project at my university. Now I've got the whole thing running as I want it to. I produce 4 images and a load of text based on the ISS's orbit parameters as our cubesat is not yet flying.
The 4 pictures are:
1) Satellite's current position on a globe based on its TLE straight from celestrak.
2) Satellite's current position on a mercator(flat) map.
3) Its current lat/lon position translated to a google earth view to physically interpret where it is.
4) Its current lat/lon position based on current weather maps, for whether or not there are clouds in the region, obscuring the satellites remote sensing imaging capabilities. (Reason why the picture looks ugly and purple, is because this region had no current weather data at the time of retrieving data)
Then I need to implement a text box with information on altitude, velocity, spatial resolution etc.
It's all nice and dandy. But I cant for the love of god figure out how to get this Tkinter GUI to play nice! I'm a geoscientist, not a computer scientist and python programming is very new to me :D
Anyway I did a quick layout in photoshop as of how I want the finished data to be produced in a Tkinter GUI. See the primitive image below:
Now here is my shameful code below:
import Tkinter as tk
from PIL import ImageTk, Image
#This creates the main window of an application
window = tk.Tk()
window.title("Satellite Control Center")
window.geometry("1000x800")
window.configure(background='grey')
#Imports the pictures.
pic1 = "Globeview.png"
pic2 = "MercatorView.png"
pic3 = "currentweathercroppedsmall.png"
pic4 = "GECurrentcroppedsmall.png"
#Creates a Tkinter-compatible photo image, which can be used everywhere Tkinter expects an image object.
img1 = ImageTk.PhotoImage(Image.open(pic1))
img2 = ImageTk.PhotoImage(Image.open(pic2))
img3 = ImageTk.PhotoImage(Image.open(pic3))
img4 = ImageTk.PhotoImage(Image.open(pic4))
#The Label widget is a standard Tkinter widget used to display a text or image on the screen.
globeview = tk.Label(window, image = img1)
mercatorview = tk.Label(window, image = img2)
currentweather= tk.Label(window, image = img3)
gearth = tk.Label(window, image = img4)
#The Pack geometry manager packs widgets in rows or columns.
globeview.pack(side = "top", fill = "both", expand = "yes")
mercatorview.pack(side = "top", fill = "both", expand = "yes")
currentweather.pack(side = "bottom", fill = "both", expand = "yes")
gearth.pack(side = "bottom", fill = "both", expand = "yes")
#Start the GUI
window.mainloop()
Which produces this horror show!
My issues are clearly:
1) Images are not aligned in any way I want. Normally in HTML I'd set up table rows, align and fit it with spacers as I want. But I don't know how to define that here and I've spend hours being frustrated of this by now.
2) I need to add a text box. Every time I've tried to add various versions of text boxes. I get weird pyimage'xx' errors and no text box seems to materialize.
3) For the future: A button under the images that will show the full size uncropped picture. But that's not imperative right now!
So I'm hoping one of you have a nice way to do this, or can point me in a direction.. or perhaps even have done something like it where I can see your code and just tweak the numbers of a bit for aligning the pixels.
Thank you in advance.
You are trying to lay everything out in a single frame. That can be done, but it's much easier to make subframes for things that fall in neat rows, columns or grids, and then put the subframes into the final arrangement.
Totally untested guess:
import Tkinter as tk
from tkFont import Font
from PIL import ImageTk, Image
#This creates the main window of an application
window = tk.Tk()
window.title("Aarhus University Satellite Control Center")
window.geometry("1000x800")
window.configure(background='grey')
#Imports the pictures.
pic1 = "Globeview.png"
pic2 = "MercatorView.png"
pic3 = "currentweathercroppedsmall.png"
pic4 = "GECurrentcroppedsmall.png"
#Creates a Tkinter-compatible photo image, which can be used everywhere Tkinter expects an image object.
img1 = ImageTk.PhotoImage(Image.open(pic1))
img2 = ImageTk.PhotoImage(Image.open(pic2))
img3 = ImageTk.PhotoImage(Image.open(pic3))
img4 = ImageTk.PhotoImage(Image.open(pic4))
header = tk.Label(window, text="Header", font=Font(size=40))
header.pack()
toprow = tk.Frame(window)
globeview = tk.Label(toprow, image = img1)
globeview.pack(side = "left") # the side argument sets this to pack in a row rather than a column
infobox = tk.Text(toprow)
infobox.pack(side = "left")
toprow.pack() # pack the toprow frame into the window
bottomrow = tk.Frame(window)
mercatorview = tk.Label(bottomrow, image = img2)
currentweather= tk.Label(bottomrow, image = img3)
gearth = tk.Label(bottomrow, image = img4)
mercatorview.pack(side = "left")
currentweather.pack(side = "left")
gearth.pack(side = "left")
bottomrow.pack()
#Start the GUI
window.mainloop()
import Tkinter as tk
from PIL import ImageTk, Image
#This creates the main window of an application
window = tk.Tk()
window.title("Aarhus University Satellite Control Center")
window.geometry("1000x800")
window.configure(background='grey')
#Imports the pictures.
pic1 = "Globeview.png"
pic2 = "MercatorView.png"
pic3 = "currentweathercroppedsmall.png"
pic4 = "GECurrentcroppedsmall.png"
#Creates a Tkinter-compatible photo image, which can be used everywhere Tkinter expects an image object.
img1 = ImageTk.PhotoImage(Image.open(pic1))
img2 = ImageTk.PhotoImage(Image.open(pic2))
img3 = ImageTk.PhotoImage(Image.open(pic3))
img4 = ImageTk.PhotoImage(Image.open(pic4))
#The Label widget is a standard Tkinter widget used to display a text or image on the screen.
globeview = tk.Label(window, image = img1).grid(row=0,column=0)
mercatorview = tk.Label(window, image = img2).grid(row=1,column=0)
currentweather= tk.Label(window, image = img3).grid(row=1,column=1)
gearth = tk.Label(window, image = img4).grid(row=1,column=2)
#Start the GUI
window.mainloop()
You need to add row and column in the label grid option. After you are creating the Label , put the grid and mention row and column . I have updated the code, just check it . If you face any problem write us back, and remove pack, which I deleted in the code :) Cheers
I am trying to use tkingter to make a card game.
set a table image as background of the canvas.
draw cards on top of the table background. This will be triggered by clicking a button (not shown here)
The problem is I can't create card image on top of table background. what's the right way to do it? do i need to create another canvas for card, in stead of directly drawing on table background? I feel there is something fundamental that i am missing here.
from tkinter import *
from PIL import Image, ImageTk
# globals
table_dir = "C:/Python36/resourse/table.png"
card_dir = "C:/Python36/resourse/card.jpg"
#CREATE APP
root = Tk()
#LOAD IMAGES
table_PIL = Image.open(table_dir)
table_image = ImageTk.PhotoImage(table_PIL)
card_PIL = Image.open(card_dir)
card_image = ImageTk.PhotoImage(card_PIL)
#make canvas and set background image with a label
canv = Canvas(root, width=table_PIL.width, height=table_PIL.height, background="white")
background_label = Label(canv, image = table_image)
background_label.place(x=0, y=0, relwidth=1, relheight=1)
canv.grid(row=0, column=0)
#trying to create card image on top of background table, not working
canv.create_image(200, 100, image=card_image)
root.mainloop()
Don't use a label for the background. Use canv.create_image(...) to create the background, just like you do for creating cards.
I have worked out how to have an image for a button, thats positioned on top of a label (I think I maybe doing it the long-winded way because I can't install PIL on my Mac for some reason). Anyhow, it works as it should to a certain degree - the problem I have is it's adding white space either side, and then the image itself is not displaying its transparent background.
The code I am using is as follows:
from tkinter import *
#from PIL import Image
root = Tk()
#Removes the title bar and places over mac top bar
root.tk.call("::tk::unsupported::MacWindowStyle", "style", root._w, "plain", "none")
# Makes the app full screen
#root.wm_attributes('-fullscreen', 1)
root.geometry('{}x{}'.format(480, 320))
#root.attributes('-topmost', True)
def quitApp():
# mlabel = Label (root, text = 'Close').pack()
root.destroy()
background_img = PhotoImage(file="images/bg.gif")
scanBtn_img = PhotoImage(file="images/scanBtn.gif")
background = Label(root,
compound = CENTER,
quitButton = Button(image=scanBtn_img, command = quitApp).pack(),
image = background_img).pack(side="right")
background.image = background_img # keep a reference!
root.mainloop()
From what I understand tkinter natively supports transparency on images like GIF.
I chopped up your code a little but it does work for me. Maybe there is a problem with how you have set up your code. Your label also has a button in it. I don't think you need to have both. You can just created the button where you want it.
Just for reference I created a Label and a Button packed on different sides with a black background to show the transparency of the image.
Here is the code I used to test a gif I have that has transparency. I tested this on both python 3.6 and 2.7 just in case.
from tkinter import *
root = Tk()
def quitApp():
root.destroy()
background_img = PhotoImage(file="Colors/sa.gif")
scanBtn_img = PhotoImage(file="Colors/sa.gif")
background = Label(root,bg='black', image = background_img).pack(side = RIGHT)
quitButton = Button(bg='black', image=scanBtn_img, command = quitApp).pack(side = LEFT)
backgroundimage = background_img # keep a reference!
root.mainloop()
Update: I used the gif you link in the comment
Here is the result.
Update:
After doing some more digging I found what might work for Mac OS:
I don't have a Mac to test on right now so let me know if this works for you:
from tkinter import *
root = Tk()
# Hide the root window drag bar and close button
root.overrideredirect(True)
# Make the root window always on top
root.wm_attributes("-topmost", True)
# Make the window content area transparent
root.wm_attributes("-transparent", True)
# Set the root window background color to a transparent color
root.config(bg='systemTransparent')
def quitApp():
root.destroy()
background_img = PhotoImage(file="Colors/1.gif")
scanBtn_img = PhotoImage(file="Colors/1.gif")
background = Label(root,bg='black', image = background_img)
background.pack(side = RIGHT)
background.config(bg='systemTransparent')
quitButton = Button(bg='black', image=scanBtn_img, command = quitApp)
quitButton.pack(side = LEFT)
quitButton.config(bg='systemTransparent')
backgroundimage = background_img # keep a reference!
root.mainloop()
I have a window with a label as my frame. I did this because i wanted an image in the background. But now im having trouble with the other labels i have used. The other labels i have used to actually labeled things dont have a transparent background. Is there a way to make the background of these labels transparent?
import Tkinter as tk
root = tk.Tk()
root.title('background image')
image1 = Tk.PhotoImage(file='image_name.gif')
# get the image size
w = image1.width()
h = image1.height()
# make the root window the size of the image
root.geometry("%dx%d" % (w, h))
# root has no image argument, so use a label as a panel
panel1 = tk.Label(root, image=image1)
panel1.pack(side='top', fill='both', expand='yes')
# put a button/label on the image panel to test it
label1 = tk.Label(panel1, text='here i am')
label1.pack(side=Top)
button2 = tk.Button(panel1, text='button2')
button2.pack(side='top')
# start the event loop
root.mainloop()
i think it can help, all black will be transparent
root.wm_attributes('-transparentcolor','black')
It is not supported with transparent backgrounds in Tk.
If you are working with images and putting text onto them, the most convenient way is - I think - utilizing Canvas widget.
tkinter Canvas widget has methods as .create_image(x, y, image=image, options) and .create_text(x, y, text="Some text", options).
use this :
from tkinter import *
main=Tk()
photo=PhotoImage(file='test.png')
Label(main,image=photo,bg='grey').pack()
#your other label or button or ...
main.wm_attributes("-transparentcolor", 'grey')
main.mainloop()
this work if use bg='grey' you can change it in line 7
good luck :)