【问题标题】:Python Turtle Tile Class BugPython Turtle Tile 类错误
【发布时间】:2020-09-05 11:36:19
【问题描述】:

我正在使用来自this answer 的代码使用 Python Turtle Graphics 制作可点击的编号图块。出于某种原因,当图块的文本相同时,我的代码使用第二个图块集(红色)而不是第一个图块集(蓝色)的颜色创建图块。

我尝试检查不同颜色的瓷砖是否以某种方式引用了同一个对象,但似乎并非如此。谁能告诉我如何解决这个问题?

from tileset_so import TileSet
from turtle import Screen

SIZE = 4
screen = Screen()

# Tiles
tileset1 = TileSet(background_color="blue")
tileset2 = TileSet(background_color="red")

tiles1 = []
tiles2 = []

blue_tile = tileset1.make_tile("here")
red_tile = tileset2.make_tile("here") # works fine with "there"
blue_tile.goto(100, 100)
red_tile.goto(-100, 100)

print(id(blue_tile), id(red_tile))
print(id(tileset1), id(tileset2))

screen.mainloop()
# tileset.py

from turtle import Screen, Turtle, Shape
from PIL import Image, ImageDraw, ImageFont, ImageTk

DEFAULT_FONT_FILE = "C:\Windows\Fonts\courbd.ttf"  # adjust for your system
DEFAULT_POINT_SIZE = 32
DEFAULT_OUTLINE_SIZE = 1
DEFAULT_OUTLINE_COLOR = 'black'
DEFAULT_BACKGROUND_COLOR = 'white'

class Tile(Turtle):
    def __init__(self, shape, size):
        super().__init__(shape)
        self.penup()

        self.size = size

    def tile_size(self):
        return self.size

class TileSet():

    def __init__(self, font_file=DEFAULT_FONT_FILE, point_size=DEFAULT_POINT_SIZE, background_color=DEFAULT_BACKGROUND_COLOR, outline_size=DEFAULT_OUTLINE_SIZE, outline_color=DEFAULT_OUTLINE_COLOR):
        self.font = ImageFont.truetype(font_file, point_size)
        self.image = Image.new("RGB", (point_size, point_size))
        self.draw = ImageDraw.Draw(self.image)

        self.background_color = background_color
        self.outline_size = outline_size
        self.outline_color = outline_color

    def register_image(self, string):
        width, height = self.draw.textsize(string, font=self.font)
        image = Image.new("RGB", (width + self.outline_size*2, height + self.outline_size*2), self.background_color)
        draw = ImageDraw.Draw(image)
        tile_size = (width + self.outline_size, height + self.outline_size)
        draw.rectangle([(0, 0), tile_size], outline=self.outline_color)
        draw.text((0, 0), string, font=self.font, fill="#000000")
        photo_image = ImageTk.PhotoImage(image)
        shape = Shape("image", photo_image)
        Screen()._shapes[string] = shape  # underpinning, not published API

        return tile_size

    def make_tile(self, string):
        tile_size = self.register_image(string)
        return Tile(string, tile_size)

【问题讨论】:

  • 您能否显示您实际使用图块的代码?否则,您究竟是如何确定颜色错误的?
  • 这是顶级sn-p。
  • 我的意思是,您绘制瓷砖的代码。我看到的代码决定了它们应该是什么样子,设置它们的位置,并检查它们是否是不同的对象。当您在Screen()._shapes 中注册图像时,我假设您可以稍后对它们进行操作。那是什么东西?

标签: python turtle-graphics


【解决方案1】:
Screen()._shapes[string] = shape  # underpinning, not published API
                                                  ^^^^^^^^^^^^^^^^^

那么当它的行为与您的预期不同时,您就不会抱怨,对吧?

Screen() 实例是单例的。因此,每次到达此行时,same 字典都会进行此分配。因此,如果这两个图块 - 即使在不同的图块集中 - 具有相同的名称,则第二个将替换此字典中的第一个。

至于 为什么这很重要 - 好吧,我想,我们必须看看最初给你写这句话的想法的地方。

【讨论】:

    【解决方案2】:

    这是我的 TileSet 代码示例中的一个错误。

    这里有一个解决方法:将 TileSet 代码中的 make_tile() 更改为:

    def make_tile(self, string, id):
        tile_size = self.register_image(string, id)
        return Tile(string + ':' + id, tile_size)
    

    在 TileSet register_image 函数中更改这两行:

    def register_image(self, string):
    
        Screen()._shapes[string] = shape  # underpinning, not published API
    

    改为阅读:

    def register_image(self, string, id):
    
        Screen()._shapes[string + ':' + id] = shape  # underpinning, not published API
    

    最后将您的呼叫更改为 make_tile() 以包含唯一描述:

    blue_tile = tileset1.make_tile("here", "blue here")
    red_tile = tileset2.make_tile("here", "red here")
    

    这应该可以解决海龟的_shapes 字典的问题。

    【讨论】:

      猜你喜欢
      • 2023-01-25
      • 1970-01-01
      • 2020-10-31
      • 1970-01-01
      • 2015-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多