Reputation: 1342
I'm a bit new to python in terms of learning Tkinter and it's ability to code a GUI. As a result, I'm trying my hand at doing a simple JPEG image on a GUI using python 2.7.3. I've seen a number of different solutions using the "self" word and I think I understand the purpose. Unfortunately, that's now how my code is laid out since I'm kind of just coding as I think of stuff at the moment. Here is how my code is set up current:
from Tkinter import *
from random import randint
from PIL import Image, ImageTk
# Global root item for using TKinter
root = Tk()
PLAYER_IMAGE_PATH = 'Path_to_image'
# Player class
class Player:
playerHp = 0
playerAtk = 0
playerDef = 0
playerImg = ''
playerPositionX = 0
playerPositionY = 0
def __init__(self, hitpoints, attackPower, defensePower, pathToImage, positionX, positionY):
self.playerHp = hitpoints
self.playerAtk = attackPower
self.playerDef = defensePower
self.playerImg = pathToImage
self.playerPositionX = positionX
self.playerPositionY = positionY
# Method for building the frame.
def build_frame(screenHeight, screenWidth):
canvas = Canvas(root, bg = 'blue', height = screenHeight, width = screenWidth)
canvas.pack()
player = create_random_player()
display_player_image(canvas, player)
#display_player_stats(frame, player)
bind_all_keys(player)
# Key binding events.
def bind_all_keys(player):
root.bind('<Left>', lambda event, arg=player: left_key(event, arg))
root.bind('<Right>', lambda event, arg=player: right_key(event, arg))
root.bind('<Up>', lambda event, arg=player: up_key(event, arg))
root.bind('<Down>', lambda event, arg=player: down_key(event, arg))
def left_key(event, player):
print "Player coordinates(X,Y): " + str(player.playerPositionX) + "," + str(player.playerPositionY)
player.playerPositionX -= 1
def right_key(event, player):
print "Player coordinates(X,Y): " + str(player.playerPositionX) + "," + str(player.playerPositionY)
player.playerPositionX += 1
def up_key(event, player):
print "Player coordinates(X,Y): " + str(player.playerPositionX) + "," + str(player.playerPositionY)
player.playerPositionY -= 1
def down_key(event, player):
print "Player coordinates(X,Y): " + str(player.playerPositionX) + "," + str(player.playerPositionY)
player.playerPositionY += 1
# End key binding events.
def create_random_player():
return Player(randint(0,9), randint(0,9), randint(0,9), PLAYER_IMAGE_PATH, 0, 0)
def display_player_image(canvas, player):
canvas.create_rectangle(50, 50, 250, 100, fill = "green")
tkImage = ImageTk.PhotoImage(Image.open(player.playerImg))
canvas.create_image(100, 100, image = tkImage, anchor = NE)
def display_player_stats(frame, player):
hitPoints = Text(frame, height = 1)
hitPoints.insert(INSERT, "HP: " + str(player.playerHp))
hitPoints.pack()
attackPower = Text(frame, height = 1)
attackPower.insert(INSERT, "Attack: " + str(player.playerAtk))
attackPower.pack()
defensePower = Text(frame, height = 1)
defensePower.insert(INSERT, "Defense: " + str(player.playerDef))
defensePower.pack()
xPos = Text(frame, height = 1)
xPos.insert(INSERT, "X Pos: " + str(player.playerPositionX))
xPos.pack()
yPos = Text(frame, height = 1)
yPos.insert(INSERT, "Y Pos: " + str(player.playerPositionY))
yPos.pack()
# Main method. Calculates height at 70% then sets width to same height to create square on screen.
def main(root):
height = root.winfo_screenheight() * 0.7
width = height
build_frame(screenHeight = height, screenWidth = width)
root.mainloop()
# Entry method.
if __name__ == "__main__":
main(root)
So, you can see that I create a player class and set the path to the JPEG in the creat_random_player method. I create my canvas and proceed to try and create my image and nothing appears. I've tried a number of things and I know some people will come on here and say I need to pass "self" but I'm not sure how to do this as is. I appreciate any input people can offer because I'm at a bit of a loss.
Also, I'm aware this code is probably sloppy but it's a first pass and I will be cleaning it up as I continue to code but this is how it is now. Please refrain from comments on code structure unless there is no other way to code the solution except to change everything.
Upvotes: 1
Views: 1687
Reputation: 11625
You're image is getting garbage collected by python's garbage collector. You need to save a reference to the image.
Here's a solution to get your playerImg to display
On your line(s)
def display_player_image(canvas, player):
canvas.create_rectangle(50, 50, 250, 100)
tkImage = ImageTk.PhotoImage(Image.open(player.playerImg))
canvas.create_image(100, 100, image = tkImage, anchor = NE)
player.playerImg = tkImage #Reference
there's other ways to save a reference in your code. This is just the quickest one i saw.
Upvotes: 3