首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python Turtle Tile类Bug

Python Turtle Tile类Bug
EN

Stack Overflow用户
提问于 2020-09-05 19:36:19
回答 2查看 78关注 0票数 0

我正在使用this answer中的代码,用Python Turtle Graphics制作可点击的编号瓦片。由于某些原因,我的代码创建了具有第二个平铺集(红色)而不是第一个平铺集(蓝色)的颜色的平铺,而这些平铺的文本是相同的。

我试着检查不同颜色的瓷砖是否以某种方式引用了同一个对象,但似乎不是这样。有没有人能告诉我怎么解决这个问题?

代码语言:javascript
复制
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()
代码语言:javascript
复制
# 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)
EN

回答 2

Stack Overflow用户

发布于 2020-09-06 01:10:56

代码语言:javascript
复制
Screen()._shapes[string] = shape  # underpinning, not published API
                                                  ^^^^^^^^^^^^^^^^^

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

Screen()实例是单例的。因此,每次到达此行时,都会对相同的字典进行此赋值。因此,如果这两个瓦片-即使在不同的瓦片集中-具有相同的名称,那么第二个瓦片将替换本词典中的第一个瓦片。

至于为什么这很重要,我想,我们必须看一下最初让你产生写这行的想法的地方。

票数 0
EN

Stack Overflow用户

发布于 2020-09-06 04:21:44

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

代码语言:javascript
复制
def make_tile(self, string, id):
    tile_size = self.register_image(string, id)
    return Tile(string + ':' + id, tile_size)

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

代码语言:javascript
复制
def register_image(self, string):

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

改为:

代码语言:javascript
复制
def register_image(self, string, id):

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

最后,将您对make_tile()的调用更改为包含唯一的描述:

代码语言:javascript
复制
blue_tile = tileset1.make_tile("here", "blue here")
red_tile = tileset2.make_tile("here", "red here")
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63753459

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档