如何使用Tkinter在Python Canvas上引用绘制事件?

时间:2017-10-26 21:18:45

标签: python canvas tkinter tk

我知道这可能是有史以来最简单的问题。但是,我开始学习Tkinter,我不知道如何在GUI上点击鼠标时引用该事件。

我想在点击画布时绘制一些点。我无法在paint函数中引用canvas变量。

这段代码基于SO

中的问题

每当我尝试这个例子时,我在paint函数中都会出现错误

  

NameError:未定义名称“canvas”;

def main():
    master = Tk()
    # Right side of the screen / img holder
    right_frame = Frame(master, width=500, height=500, cursor="dot")
    right_frame.pack(side=LEFT)

    # Retrieve image
    image = Image.open("./image/demo.JPG")
    image = image.resize((800, 700), Image.ANTIALIAS)
    photo = ImageTk.PhotoImage(image)

    # Create canvas
    canvas = Canvas(right_frame, width=800, height=700)
    canvas.create_image(0, 0, image=photo, anchor="nw")
    canvas.pack()
    canvas.bind("<B1-Motion>", paint)
    message = Label(right_frame, text="Press the mouse to draw")
    message.pack(side=BOTTOM)


    mainloop()


def paint(event):
    python_green = "#476042"
    x1, y1 = (event.x - 1), (event.y - 1)
    x2, y2 = (event.x + 1), (event.y + 1)
    canvas.create_oval(x1, y1, x2, y2, fill=python_green)


if __name__ == "__main__":
    main()

1 个答案:

答案 0 :(得分:2)

这是python的范围规则的一个简单错误。您在函数中创建的变量不能在该函数之外使用。

>>> def func():
...   a = 42
... 
>>> func()
>>> a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined

您必须将画布传递给paint函数。要通过bind执行此操作,我们需要创建一个“闭包”,我们可以使用functools.partial函数执行此操作。

from tkinter import *
from functools import partial

def main():
    master = Tk()
    # Right side of the screen / img holder
    right_frame = Frame(master, width=500, height=500, cursor="dot")
    right_frame.pack(side=LEFT)

    # Create canvas
    canvas = Canvas(right_frame, width=800, height=700)
    canvas.create_image(0, 0, image=photo, anchor="nw")
    canvas.pack()
    canvas.bind("<B1-Motion>", partial(paint, canvas))
    message = Label(right_frame, text="Press the mouse to draw")
    message.pack(side=BOTTOM)

    mainloop()

def paint(canvas, event):
    python_green = "#476042"
    x1, y1 = (event.x - 1), (event.y - 1)
    x2, y2 = (event.x + 1), (event.y + 1)
    canvas.create_oval(x1, y1, x2, y2, fill=python_green)

if __name__ == "__main__":
    main()

你真的应该考虑这类程序的类结构,这样你就可以将变量用于其他方法。