在类内的画布中创建图像 [英] Create an image in a canvas inside a class

查看:34
本文介绍了在类内的画布中创建图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 OOP 创建一个国际象棋程序.所以我做了一个超类Pieces、一个子类Bishop和一个UI类GameUI.我在类 GameUI 中创建了一个画布.我想要,当我在 GameUI 类中实例化一个对象 bishop 时,它会在画布上显示一个来自主教的图像.

I wanted to create a chess program using OOP. So I made a superclass Pieces, a subclass Bishop, and a UI class GameUI. I created a canvas in the class GameUI. I wanted, that when I instantiate an object bishop in the class GameUI, it shows an Image from a bishop, on the canvas.

问题是,当我实例化 Bishop 时,我看不到任何图像.所以我尝试对文本做同样的事情:我没有使用 Canvas 类中的 create_image 方法,而是使用了 create_text 方法,它起作用了:我在画布上看到了一个文本.也就是说,问题出在create_image方法上,我不明白.

The problem is, when I instantiate the Bishop, I don't see any image. So I tried to do the same with a text : instead of using the method create_image from the class Canvas, I used the method create_text, and it worked : I saw a text on the canvas. That means, the problem comes from the method create_image, and I don't understand it.

如果我直接在 GameUi 类中创建一个图像,它会起作用!但这不是我想要的...

If I create an Image directly in the class GameUi, it works! but that's not what I want...

所以我没有任何错误信息.我看到画布(蓝色背景),但上面没有图像.

So I don't have any error message. I see the canvas (with a blue background), but no image on it.

代码如下:

from tkinter import PhotoImage, Tk, Canvas


class Pieces:

    def __init__(self, can, color, x_position, y_position):
        self.color = color
        self.x_position = x_position
        self.y_position = y_position


class Bishop(Pieces):

    def __init__(self, can, color, x_position, y_position):

        super().__init__(can, color, x_position, y_position)

        if color == "black":
            icon_path = 'black_bishop.png'
        elif color == "white":
            icon_path = 'white_bishop.png'

        icon = PhotoImage(file=icon_path)  # doesn't see the image
        can.create_image(x, y, image=icon)


class GameUI:

    def __init__(self):

        self.windows = Tk()
        self.windows.title("My chess game")
        self.windows.geometry("1080x720")
        self.windows.minsize(300, 420)

        self.can = Canvas(self.windows, width=1000, height=600, bg='skyblue')
        
        icon = PhotoImage(file=icon_path)  # here I create the image in this class, and
        can.create_image(x, y, image=icon)  # we can see it very well

        self.bishop = Bishop(self.can, "black", 50, 50)
        self.can.pack()
        self.windows.mainloop()


app = GameUI()

推荐答案

为了让你的代码工作,我决定基于 这个答案.它现在可以工作了,但实际上您唯一需要添加的是 self.icon 而不是 icon.icon 被垃圾收集,因为没有进一步引用它,而 self.icon 仍然存在.此外,它与您的并不完全相同,因此它可能也需要一些重写.

To make your code work, I decided to sort of rewrite it based on this answer. It works now, but really the only thing that you needed to add was self.icon instead of icon. icon gets garbage collected since there is no further reference to it, while self.icon remains. Also, it's not entirely the same as yours was, so it probably needs a bit of rewriting too.

from tkinter import *
from random import randint

class Piece:
    def __init__(self, canvas, x1, y1):
        self.x1 = x1
        self.y1 = y1
        self.canvas = canvas

class Bishop(Piece):
    def __init__(self, canvas, x1, y1, color):
        super().__init__(canvas, x1, y1)

        if color == "black":
            icon_path = 'black_bishop.png'
        elif color == "white":
            icon_path = 'white_bishop.png'

        self.icon = PhotoImage(file=icon_path)
        self.ball = canvas.create_image(self.x1, self.y1, image=self.icon)

    def move_piece(self):
        deltax = randint(0,5)
        deltay = randint(0,5)
        self.canvas.move(self.ball, deltax, deltay)
        self.canvas.after(50, self.move_piece)

class GameUI:
    def __init__(self):
        # initialize root Window and canvas
        root = Tk()
        root.title("Chess")
        root.resizable(False,False)
        canvas = Canvas(root, width = 300, height = 300)
        canvas.pack()

        # create two ball objects and animate them
        bishop1 = Bishop(canvas, 10, 10, 'white')
        bishop2 = Bishop(canvas, 60, 60, 'black')

        bishop1.move_piece()
        bishop2.move_piece()

        root.mainloop()

app = GameUI()

这篇关于在类内的画布中创建图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆