Событие активируется перед щелчком мыши (Python, Tkinter)

Я работаю над кодом для перемещения фигуры, нарисованной на холсте. В целом это программа для векторного рисования, поэтому мне нужно иметь возможность перемещать одну фигуру, а затем другую.

Пока у меня есть код, который работает для перемещения одной фигуры, но когда я затем пытаюсь переместить другую фигуру, которая появляется на экране, фигура прыгает, прежде чем я могу щелкнуть по ней. Я думаю, что происходит то, что код для перемещения фигуры активируется без щелчка, и поэтому координаты в коде не сбрасываются, вызывая скачок фигуры (код, который у меня есть, должен получить координаты второго форма, когда она нажата, я надеюсь)

Я пытался найти в Интернете любую причину, по которой он работает без щелчка, но ничего не нашел. Я также попытался отвязать теги, которые перемещают фигуру после размещения первой фигуры, чтобы они не были привязаны до тех пор, пока не будет нажата вторая фигура, но это, похоже, не сработало.

Кто-нибудь может объяснить, что здесь происходит?

#code for a two shapes
circle = Main_Window.create_image(500,400, image = CircleIm, tags = "circle")
shape = circle
type1 = Move_Shape(shape)
Main_Window.tag_bind(circle, "<ButtonPress-3>", type1.moveShape(shape))

triangle= Main_Window.create_image(500,400, image = TriangleIm, tags = "triangle")
shape = triangle
type1 = Move_Shape(shape)
Main_Window.tag_bind(triangle, "<ButtonPress-3>", type1.moveShape(shape))


class Move_Shape:
    def __init__(self, shape):
        self.shape = shape
        return

def getShapeType(self, shape):
    global shapeType
    print(self.shape)
    shapeType = Main_Window.gettags(self.shape)  
    return shapeType

def moveShape(self, shape):
    #while left button is held down, we want it to move the tagged shape to     move to the position of the mouse
    global b1, currentX, currentY
    b1 = "down"
    newX, newY = None, None
    shapeType = self.getShapeType(shape)
    print(shapeType)

    Main_Window.addtag_withtag("move_shape", shapeType[0])
    #Bind move_shape to moving code
    print("new tags are", Main_Window.gettags(self.shape))
    Main_Window.tag_bind("move_shape","<Motion>", self.whileMoving)
    Main_Window.tag_bind("move_shape","<ButtonPress-3>", self.getCurrentCoords)
    Main_Window.tag_bind("move_shape", "<ButtonPress-1>", self.startMoving)
    Main_Window.tag_bind("move_shape", "<ButtonRelease-1>", self.stopMoving)
    root_window.mainloop() 
    return shape


def getCurrentCoords(self, event):
    global currentX, currentY
     #make sure the coordinates are obtained before user tries to move shape
    coords = Main_Window.coords(shapeType[0])
    currentX= coords[0]
    currentY = coords[1]
    return currentX, currentY

def startMoving(self,event):
    global b1
    b1 = "down"
    return

def stopMoving(self, event):
    global b1
    b1 = "up"
    newX = None     
    newY = None

    return b1, newX, newY

def whileMoving(self, event):
    global shapeType, b1, currentX, currentY
    if b1 == "down":
        newX = event.x
        newY = event.y
        if newX is not None  and newY is not None:
            x = newX - currentX
            y = newY - currentY
            Main_Window.move(shapeType[0],x,y)
            currentX = newX
            currentY = newY
            newX = event.x
            newY= event.y
        return

person M.K.P    schedule 07.03.2016    source источник


Ответы (1)


Чтобы связать функцию с аргументами, используйте ключевое слово lambda:

Main_Window.tag_bind(triangle, "<ButtonPress-3>", lambda shape: type1.moveShape(shape))  

Если вы сделаете Main_Window.tag_bind(triangle, "<ButtonPress-3>", type1.moveShape(shape)), Python вызовет функцию обратного вызова перед созданием виджета и передаст возвращаемое значение функции в Tkinter. Затем Tkinter пытается преобразовать возвращаемое значение в строку и говорит Tk вызывать функцию с этим именем при активации кнопки. Это, вероятно, не то, что вы хотели.

Для таких простых случаев, как этот, вы можете использовать лямбда-выражение в качестве связи между Tkinter и функцией обратного вызова (я взял это объяснение effbot. орг)

person Kenly    schedule 07.03.2016
comment
Это сработало, спасибо. Не могли бы вы объяснить, что он делает, что исправлено? - person M.K.P; 08.03.2016
comment
Спасибо за помощь. - person M.K.P; 13.03.2016