Добавление изображения JPEG на холст Tkinter

Я немного новичок в python с точки зрения изучения Tkinter и его способности кодировать графический интерфейс. В результате я пытаюсь сделать простое изображение JPEG в графическом интерфейсе, используя python 2.7.3. Я видел несколько различных решений, использующих слово «я», и я думаю, что понимаю цель. К сожалению, теперь мой код выглядит именно так, поскольку я просто пишу код, когда думаю о вещах в данный момент. Вот как мой код настроен в настоящее время:

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)

Итак, вы можете видеть, что я создаю класс игрока и задаю путь к JPEG в методе creat_random_player. Я создаю свой холст и продолжаю пытаться создать свое изображение, и ничего не появляется. Я пробовал несколько вещей, и я знаю, что некоторые люди придут сюда и скажут, что мне нужно передать «я», но я не уверен, как это сделать как есть. Я ценю любой вклад, который могут предложить люди, потому что я немного в растерянности.

Кроме того, я знаю, что этот код, вероятно, неряшлив, но это первый проход, и я буду чистить его, когда буду продолжать писать код, но сейчас это так. Пожалуйста, воздержитесь от комментариев по структуре кода, если нет другого способа закодировать решение, кроме как изменить все.


person Michael Platt    schedule 28.03.2016    source источник
comment
локальные переменные удаляются сборщиком мусора при выходе из функции, поэтому после этого tkImage не существует. См. www.effbot.org/pyfaq/why-do-my-tkinter-images-not-appear.htm. В вашем случае вы можете добавить его в экземпляр холста, canvas.image=ImageTk.PhotoImage и т.д.   -  person    schedule 29.03.2016
comment
Возможный дубликат изображения холста tkinter не отображается   -  person Terry Jan Reedy    schedule 29.03.2016
comment
Поиск SO для [tkinter] display canvas image, например, выдает несколько предыдущих вопросов с одним и тем же ответом.   -  person Terry Jan Reedy    schedule 29.03.2016
comment
Если бы я мог голосовать, я бы VTC: заголовок stackoverflow.com/questions/16424091/   -  person WinEunuuchs2Unix    schedule 03.12.2019


Ответы (1)


Ваше изображение получает мусор, собранный сборщиком мусора Python. Вам нужно сохранить ссылку на изображение.

Вот решение для отображения вашего playerImg

На вашей линии

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

есть и другие способы сохранить ссылку в коде. Это просто самое быстрое, что я видел.

person Pythonista    schedule 28.03.2016
comment
Так что это решение сработало отлично, и поэтому я отмечу его как решение вопроса. Я ценю ответ. Вы упомянули, что есть другие способы сохранить ссылку в моем коде, мне было любопытно, не могли бы вы уточнить? Я пытаюсь оптимизировать свой код по мере прохождения, поэтому знание лучшего способа изменит мир в будущем. - person Michael Platt; 29.03.2016