Python Turtle Multiple Click События - PullRequest
       2

Python Turtle Multiple Click События

0 голосов
/ 25 апреля 2018

Я пытаюсь создать черепашью версию головоломки 8-Queens, используя Python Turtle.

Я только что начал, но столкнулся с блоком из-за того факта, что событие click было выбраноЧерепаха объект, кажется, стреляет только один раз.Я знаю, что события нажатия на экран запускаются несколько раз, так это особенность экземпляров Turtle?Чего мне не хватает, пожалуйста?

import turtle

screen = turtle.Screen()
screen.reset()
SIZE = 40
screen.register_shape('box', ((-SIZE/2, SIZE/2), (SIZE/2, SIZE/2), (SIZE/2, -SIZE/2), (-SIZE/2, -SIZE/2)))
screen.register_shape('images/queenlogo40x40.gif')

class Box(turtle.Turtle):
    def __init__(self, x=0, y=0, place_color='green'):
        super(Box, self).__init__()
        self.place_color = place_color
        self.speed(0)
        self.penup()
        self.shape("box")
        self.color(place_color)
        self.setpos(x, y)
        self.has_queen = False
        self.onclick(self.click_handler)

    def click_handler(self, x, y):
        print("start:" , self.has_queen)

        if self.has_queen:
            self.shape('box')
            self.has_queen = False
        else:
            self.shape('images/queenlogo40x40.gif')
            self.has_queen = True

        print("end:" , self.has_queen)


    def __str__(self):
        """ Print piece details """
        return "({0}, {1}), {2}".format(self.xcor(), self.ycor(), self.place_color())

Редактировать: я могу это исправить, добавив self.onclick(self.click_handler) в обработчик кликов, но это только кажется неправильным.Я уверен, что видел подобные функции без необходимости перепривязывать событие каждый раз, когда оно используется.

1 Ответ

0 голосов
/ 25 апреля 2018

Ваш пример должен работать правильно, я не вижу концептуальной проблемы.

Но в черепахе есть сбой. Информация о onclick хранится в свойстве _item черепахи:

self.screen._onclick(self.turtle._item, fun, btn, add)

Но когда вы изменяете форму черепахи с изображения на многоугольник или наоборот, она уничтожает свойство _item:

if self._type in ["image", "polygon"]:
        screen._delete(self._item)

Так что ваша привязка потеряна. Обратите внимание, что если вы измените строку:

self.shape('images/queenlogo40x40.gif')

вместо этого будет:

self.shape('turtle')

код работает нормально, так как вы переходите от полигона к полигону и _item сохраняется. Поэтому добавление self.onclick(self.click_handler) после изменения формы необходимо при переходе между полигоном и изображением.

Я переработал ваш код чуть ниже, чтобы решить пару не связанных проблем (например, исправлен super() вызов для Python 3; удалены неправильные символы скобок в __str__() коде.)

from turtle import Turtle, Screen

SIZE = 40

class Box(Turtle):
    def __init__(self, x=0, y=0, place_color='green'):
        super().__init__('box')

        self.speed('fastest')
        self.color(place_color)
        self.place_color = place_color
        self.has_queen = False
        self.penup()
        self.setpos(x, y)

        self.onclick(self.click_handler)

    def click_handler(self, x, y):

        print("start:", self.has_queen)

        if self.has_queen:
            self.shape('box')
        # else:
            # self.shape('turtle')
        else:
            self.shape('queenlogo40x40.gif')

        self.has_queen = not self.has_queen
        self.onclick(self.click_handler)  # redo since self.shape() may undo this

        print("end:", self.has_queen)

    def __str__(self):
        """ Print piece details """
        return "({0}, {1}), {2}".format(self.xcor(), self.ycor(), self.place_color)

screen = Screen()
screen.register_shape('box', ((-SIZE/2, SIZE/2), (SIZE/2, SIZE/2), (SIZE/2, -SIZE/2), (-SIZE/2, -SIZE/2)))
screen.register_shape('queenlogo40x40.gif')

tortoise = Box()

screen.mainloop()
...