简体   繁体   English

鼠标单击之前激活了事件(Python,Tkinter)

[英]Event activated before mouse click (Python, Tkinter)

I'm working on some code to move a shape drawn on a canvas. 我正在编写一些代码来移动在画布上绘制的形状。 It's a vector drawing program overall so I need to be able to move one shape, and then another. 总体来说,这是一个矢量绘图程序,因此我需要能够先移动一个形状,然后再移动另一个形状。

So far I have code that works for moving one shape, but when I then try to move another shape that is on the screen afterwards, the shape jumps before I can click it. 到目前为止,我的代码可以移动一个形状,但是当我随后尝试移动屏幕上的另一个形状时,该形状会在我单击之前跳转。 I think what is happening is that the code for moving the shape is being activated without a click, and so the coordinates in the code aren't being reset, causing the shape to jump (the code I have should get the coordinates of the second shape when it's clicked, I hope) 我认为发生的事情是无需单击即可激活用于移动形状的代码,因此不会重置代码中的坐标,从而导致形状跳跃(我拥有的代码应获取第二个坐标我希望它单击时的形状)

I tried looking online for any reason why it's working without a click, but didn't find anything. 我试图以任何理由尝试在线查找,但都无法点击,但没有找到任何东西。 I also tried unbinding the tags that move the shape after the first shape was placed, so that they wouldn't be bound until the second shape was clicked, but that didn't seem to work. 我还尝试取消绑定在放置第一个形状后移动形状的标签,以使它们在单击第二个形状之前不会被绑定,但这似乎不起作用。

Can anyone explain what's happening here? 谁能解释一下这里发生了什么?

#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

To bind a function with arguments, use lambda keyword: 要将函数与参数绑定,请使用lambda关键字:

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

If you do Main_Window.tag_bind(triangle, "<ButtonPress-3>", type1.moveShape(shape)) , Python will call the callback function before creating the widget, and pass the function's return value to Tkinter. 如果执行Main_Window.tag_bind(triangle, "<ButtonPress-3>", type1.moveShape(shape)) ,Python将在创建小部件之前调用回调函数,并将该函数的返回值传递给Tkinter。 Tkinter then attempts to convert the return value to a string, and tells Tk to call a function with that name when the button is activated. 然后,Tkinter尝试将返回值转换为字符串,并在按钮被激活时告诉Tk用该名称调用一个函数。 This is probably not what you wanted. 这可能不是您想要的。

For simple cases like this, you can use a lambda expression as a link between Tkinter and the callback function (I took this explanation of effbot.org ) 对于像这样的简单情况,您可以使用Lambda表达式作为Tkinter和回调函数之间的链接(我接受了effbot.org的解释)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM