pythonpython-3.xtkinterphotoimage

My image is not transparent when I am using ImageTk


I am trying to put an image into a window with ImageTk and PhotoImage. Below is the code:

import tkinter as tk
import random as r
from PIL import ImageTk, Image


window = tk.Tk()

HEIGHT = window.winfo_screenwidth()
WIDTH = window.winfo_screenheight()
RESOL = str(str(HEIGHT) + "x" + str(WIDTH+7) + "+" + str(-7) + "+" + str(0))
window.geometry(RESOL)

x = int(HEIGHT)/2
y = int(WIDTH)/2
updatex = HEIGHT + (0.6 * HEIGHT)

main = tk.Frame(window, height = WIDTH, width = HEIGHT)
main.configure(bg = "white", highlightthickness = 0)
main.place(x = x, y = y, anchor = "center")

Map = tk.Canvas(window, height = int((900 - int(x))) + int(900), width = int((900 - int(y))) + int(900), bg = "#44b863", highlightthickness = 0)
Map.place(x = updatex, y = int(y), anchor = "center")

p = tk.PhotoImage(file = "TitleForGameReal.png")
play_solo_image = tk.PhotoImage(file = "PlaySoloButton.png")
play_duo_image = tk.PhotoImage(file = "PlayDuoButton.png")

title = tk.Label(main, image = p, highlightthickness = 0, bd = 0)
title.place(relx = 0.5, rely = 0.35, anchor = "center")

class CustomButton:
    def __init__(self, image, master, height, width, bordercolor):
        self.master = master
        self.frame = tk.Frame(master, height = height, width = width, highlightthickness = 0)
        self.image = tk.Label(self.frame, image = image, borderwidth = 0, bg = "dark grey")
        self.bordercolor = bordercolor
    def put(self, x, y, command):
        self.x, self.y = x, y
        self.frame.place(relx = x, rely = y, anchor = "center")
        self.image.pack()

        def enter(event = "<Enter>"):
            self.image.config(borderwidth = 3)
        self.image.bind("<Enter>", enter)

        def leave(event = "<Leave>"):
            self.image.config(borderwidth = 0)
        self.image.bind("<Leave>", leave)
        def bind_command(event = "<Button-1>"):
            command()
        self.image.bind("<Button -1>", bind_command)


def solo():
    global x, y, updatex
    for i in range(int(int(int(HEIGHT/9))/2)):
        x -= 20
        updatex -= 20
        main.place(x = x, y = y, anchor = "center")
        Map.place(x = updatex, y = y, anchor = "center")
        main.update()
        Map.update()
    player_image = Image.open("Connector.png")
    player_image2 = ImageTk.PhotoImage(player_image)
    
    class Player:
        def __init__(self, hp, image):
            self.hp = hp
            self.image = tk.Label(Map, image = image)
            
            self.image.place(relx = 0.5, rely = 0.5, anchor = "center")
        def spawn(self):
            Map.create_image(updatex, y, image = self.image)
    player = Player(100, player_image2)
    player.spawn()

def duo():
    print("duo")

play_solo_image = tk.PhotoImage(file = "PlaySoloButton.png")
play_solo_button = CustomButton(image = play_solo_image, master = main, height = play_solo_image.height(), width = play_solo_image.width(), bordercolor = "grey")
play_solo_button.put(x = 0.39, y = 0.47, command = solo)

play_duo_button = CustomButton(image = play_duo_image, master = main, height = play_duo_image.height(), width = play_duo_image.width(), bordercolor = "grey")
play_duo_button.put(x = 0.61, y = 0.47, command = duo)

I will also leave the image as a reference, because I edited the photo to strictly have a transparent background in PhotoShop:

enter image description here

But this is the output I see:

enter image description here

Later I realized that I was also receiving an error, which may or may not have something to do with my issue:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\offcampus\AppData\Local\Programs\Python\Python35\lib\idlelib\run.py", line 125, in main
    seq, request = rpc.request_queue.get(block=True, timeout=0.05)
  File "C:\Users\offcampus\AppData\Local\Programs\Python\Python35\lib\queue.py", line 172, in get
    raise Empty
queue.Empty

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\offcampus\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 1559, in __call__
    return self.func(*args)
  File "C:\Users\offcampus\Desktop\New folder\SurvivalGame.py", line 50, in bind_command
    command()
  File "C:\Users\offcampus\Desktop\New folder\SurvivalGame.py", line 75, in solo
    player.spawn()
  File "C:\Users\offcampus\Desktop\New folder\SurvivalGame.py", line 73, in spawn
    Map.create_image(updatex, y, image = self.image)
  File "C:\Users\offcampus\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 2338, in create_image
    return self._create('image', args, kw)
  File "C:\Users\offcampus\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 2329, in _create
    *(args + self._options(cnf, kw))))
_tkinter.TclError: image ".2469091717696.2469132063968" doesn't exist

I know this may have something to do with garbage collection, and I would normally save a reference of it, but the problem is I can't do that since it will tell me "you can't pack a PhotoImage".

This is the tutorial I used to make the image background transparent. It's not my video, so don't flag it as spam.


Solution

  • The problem is image option of Map.create_image(updatex, y, image = self.image) requires a PhotoImage instance but you're giving it a label, so to fix it just say.

    class Player:
        def __init__(self, hp, image):
            self.hp = hp
            self.image = image #creating an instance variable
            self.pic = ImageTk.PhotoImage(self.image) #making an photoimage instance
            self.cv = Map.create_image(updatex, y, image = self.pic) #passing the photo image instance
            self.pic.image = self.pic #keeping a reference to the image
    

    Hope this has solved the error, do let me know if any errors or doubts.