tkinter Canvas - <enter>使用堆叠的canvas元素绑定无限循环

时间:2017-11-01 11:04:59

标签: python canvas tkinter

我正在使用python tkinter 8.5框架创建轮盘模拟器(由于某些限制),并且对绑定回调命令的概念相对较新。

当用户将鼠标悬停在画布上的某个矩形上时,所需的效果是圆圈出现在其中心(代表芯片)。 我当前的源代码很好地工作,但是当用户在矩形内盘旋时,我会遇到问题。它产生一个无限循环,交替调用矩形的进入和退出回调。

下面是我创建板块(矩形)并处理其用户交互的类(请原谅可疑的缩进)。

from tkinter import *
import uuid

class Point:

    def __init__(self, x, y):
        self.x = x
        self.y = y

class Board_Piece:

    def clicked(self, event):

        print("{} was clicked.".format(self.id))

    def on_entry(self, event):

        print("Entered box")

        chip_side_length = 20

        x1, y1 = (self.top_left.x+(self.width/2)-chip_side_length/2), (self.top_left.y+(self.height/2)-chip_side_length/2)
        x2, y2 = x1 + chip_side_length, y1 + chip_side_length
        self.bet_token_circle = self.parent.create_oval(x1, y1, x2, y2, fill="yellow")

    def on_exit(self, event):

        print("Exitted box")

        self.parent.delete(self.bet_token_circle)

    def enable(self):

        self.rectangle = self.parent.create_rectangle(self.top_left.x, self.top_left.y, self.top_left.x+self.width, self.top_left.y+self.height, fill=self.bg, outline='white', tags="{}".format(self.id))

        text_displacement = 0
        x1, y1 = (self.top_left.x+(self.width/2)-text_displacement/2), (self.top_left.y+(self.height/2)-text_displacement/2)
        self.parent.create_text(x1, y1 ,fill="white",font="Arial 10 bold", text=self.text)

        self.parent.tag_bind(self.id, "<Button-1>", self.clicked)
        self.parent.tag_bind(self.id, "<Enter>", self.on_entry)
        self.parent.tag_bind(self.id, "<Leave>", self.on_exit)

    def __init__(self, parent, x, y, width, height, text, bg):

        self.parent = parent
        self.bg = bg
        self.id = uuid.uuid4().hex
        self.top_left = Point(x, y)
        self.width = width
        self.text = text
        self.height = height

root = Tk()

canvas = Canvas(root, width=1000, height=1000, bg="#237B1A")
canvas.pack()

board_piece = Board_Piece(canvas, 100, 100, 50, 50, "8",'red')

board_piece.enable()

mainloop()

提前致谢!任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

如果光标到达芯片,你会得到一个离开事件。 通过leave-event删除芯片,光标再次在矩形上。 芯片由enter-event创建,光标再次在芯片上,依此类推。

为了避免这种情况,只有在传递矩形的外边框时才会发生这两个事件,例如以这种方式:

def on_entry(self, event):      
    if (event.x <= self.top_left.x or event.x >=self.top_left.x + self.width) or (event.y <= self.top_left.y or event.y  >= self.top_left.y + self.height):
        print("Entered box")
        chip_side_length = 20
        x1, y1 = (self.top_left.x+(self.width/2)-chip_side_length/2), (self.top_left.y+(self.height/2)-chip_side_length/2)
        x2, y2 = x1 + chip_side_length, y1 + chip_side_length
        self.bet_token_circle = self.parent.create_oval(x1, y1, x2, y2, fill="yellow")        
    else:
        pass

def on_exit(self, event):       
    if self.top_left.x < event.x < self.top_left.x + self.width and self.top_left.y < event.y < self.top_left.y + self.height:
        pass       
    else:
        print("Exitted box")
        self.parent.delete(self.bet_token_circle)