【问题标题】:Adding JPEG Image to Tkinter Canvas将 JPEG 图像添加到 Tkinter 画布
【发布时间】:2016-03-28 20:40:08
【问题描述】:

在学习 Tkinter 和编写 GUI 的能力方面,我对 python 有点陌生。因此,我正在尝试使用 python 2.7.3 在 GUI 上制作简单的 JPEG 图像。我见过许多使用“自我”一词的不同解决方案,我想我理解其目的。不幸的是,这就是我的代码现在的布局方式,因为我现在只是在编写代码。这是我的代码当前设置的方式:

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)

因此,您可以看到我创建了一个播放器类并在 creat_random_player 方法中设置了 JPEG 的路径。我创建了我的画布并继续尝试创建我的图像,但什么也没有出现。我已经尝试了很多事情,我知道有些人会来这里说我需要传递“自我”,但我不确定如何按原样执行此操作。我很感激人们能提供的任何意见,因为我有点不知所措。

另外,我知道这段代码可能很草率,但这是第一次通过,我会在继续编写代码时对其进行清理,但现在就是这样。请不要在代码结构上使用 cmets,除非除了更改所有内容之外没有其他方法可以对解决方案进行编码。

【问题讨论】:

  • 局部变量在函数退出时被垃圾回收,因此 tkImage 在那之后不存在。请参阅 www.effbot.org/pyfaq/why-do-my-tkinter-images-not-appear.htm。在您的情况下,您可以将其添加到画布实例 canvas.image=ImageTk.PhotoImage 等。
  • 例如,在 SO 中搜索 [tkinter] display canvas image,会发现多个具有相同答案的先前问题。
  • 如果我可以投票,我会投票 VTC:stackoverflow.com/questions/16424091/…

标签: python-2.7 canvas tkinter tkinter-canvas


【解决方案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

还有其他方法可以在代码中保存引用。这是我见过的最快的。

【讨论】:

  • 所以这个解决方案工作得很好,因此我将把它标记为问题的解决方案。我很欣赏你的回应。您提到还有其他方法可以在我的代码中保存引用,我很好奇您能否详细说明?我正在努力优化我的代码,所以知道更好的方法会让世界变得不同。
猜你喜欢
  • 2015-05-19
  • 2020-07-02
  • 1970-01-01
  • 2019-09-06
  • 1970-01-01
  • 2011-10-20
  • 2020-04-30
  • 2015-06-25
  • 1970-01-01
相关资源
最近更新 更多