如何使用 Tkinter 在 Python Canvas 上引用绘制事件?
How reference back a paint event on Python Canvas using Tkinter?
我知道这可能是有史以来最简单的问题。但是,我开始学习 Tkinter,但我不知道如何在 GUI 上单击鼠标时返回事件。
点击canvas我想画点。我无法在 paint 函数中引用 canvas 变量。
这段代码是基于中的问题
每当我尝试这个例子时,我都会在绘画函数中收到一个错误,上面写着
NameError: name 'canvas' is not defined;
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()
这是 python 范围规则的一个简单错误。您在函数中创建的变量无法在该函数之外使用。
>>> def func():
... a = 42
...
>>> func()
>>> a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
您必须将 canvas 传递给绘画函数。要通过 bind
做到这一点,我们需要创建一个 "closure",我们可以使用 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()
您真的应该为这些类型的程序考虑一个 class 结构,这样您就可以使变量可用于其他方法。
我知道这可能是有史以来最简单的问题。但是,我开始学习 Tkinter,但我不知道如何在 GUI 上单击鼠标时返回事件。
点击canvas我想画点。我无法在 paint 函数中引用 canvas 变量。
这段代码是基于
每当我尝试这个例子时,我都会在绘画函数中收到一个错误,上面写着
NameError: name 'canvas' is not defined;
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()
这是 python 范围规则的一个简单错误。您在函数中创建的变量无法在该函数之外使用。
>>> def func():
... a = 42
...
>>> func()
>>> a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
您必须将 canvas 传递给绘画函数。要通过 bind
做到这一点,我们需要创建一个 "closure",我们可以使用 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()
您真的应该为这些类型的程序考虑一个 class 结构,这样您就可以使变量可用于其他方法。