用鼠标点击绘制矩形[Python] def xaxis(事件): x1,y1=(事件x-1),(事件y-1) def yaxis(事件): x2,y2=(事件x+1),(事件y+1) def创建(事件): w、 创建_矩形(x1,y1,x2,y2,fill='Black') w=画布(根,宽度=画布宽度,高度=画布高度) w、 配置(cursor='cross') w、 打包(展开=是,填充=两者) w、 绑定(“,xaxis) w、 绑定(“,yaxis) w、 绑定(“,创建)

用鼠标点击绘制矩形[Python] def xaxis(事件): x1,y1=(事件x-1),(事件y-1) def yaxis(事件): x2,y2=(事件x+1),(事件y+1) def创建(事件): w、 创建_矩形(x1,y1,x2,y2,fill='Black') w=画布(根,宽度=画布宽度,高度=画布高度) w、 配置(cursor='cross') w、 打包(展开=是,填充=两者) w、 绑定(“,xaxis) w、 绑定(“,yaxis) w、 绑定(“,创建),python,drawing,tkinter,rectangles,Python,Drawing,Tkinter,Rectangles,贝壳说 Tkinter回调回溯中出现异常(最近一次调用最后一次): 文件 “/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py”, 第1410行,在呼叫中 在创建中返回self.func(*args)文件“/Users/Leo/Desktop/draw.py”,第22行 w、 创建矩形(x1,y1,x2,y2,fill='Black')名称错误:未定义全局名称“x1” 它认为creat

贝壳说

Tkinter回调回溯中出现异常(最近一次调用最后一次):
文件 “/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py”, 第1410行,在呼叫中 在创建中返回self.func(*args)文件“/Users/Leo/Desktop/draw.py”,第22行 w、 创建矩形(x1,y1,x2,y2,fill='Black')名称错误:未定义全局名称“x1”

它认为create函数不能得到其他函数的坐标

我这样做是因为我以后需要坐标

我希望你能帮助我…-)
谢谢

您只能在各自的功能(例如
xaxis
)中本地设置
x1
等,因此它们不能用于
创建
。您可以重写这些,以便它们返回所需的结果:

def xaxis(event):
   x1, y1 = (event.x - 1), (event.y - 1)

def yaxis(event):
   x2, y2 = (event.x + 1), (event.y + 1)

def create(event):
   w.create_rectangle(x1,y1,x2,y2,fill='Black')

w = Canvas(root, width=canvas_width, height=canvas_height)
w.config(cursor='cross')
w.pack(expand=YES, fill=BOTH)
w.bind("<Button-1>", xaxis)
w.bind("<ButtonRelease-1>", yaxis)
w.bind("<ButtonRelease-1>", create)

您仅在各自的功能(例如
xaxis
)中本地设置了
x1
等,因此它们不能用于
create
。您可以重写这些,以便它们返回所需的结果:

def xaxis(event):
   x1, y1 = (event.x - 1), (event.y - 1)

def yaxis(event):
   x2, y2 = (event.x + 1), (event.y + 1)

def create(event):
   w.create_rectangle(x1,y1,x2,y2,fill='Black')

w = Canvas(root, width=canvas_width, height=canvas_height)
w.config(cursor='cross')
w.pack(expand=YES, fill=BOTH)
w.bind("<Button-1>", xaxis)
w.bind("<ButtonRelease-1>", yaxis)
w.bind("<ButtonRelease-1>", create)
解决“全局名称'x1'未定义”问题 调试时的一个好的经验法则是假设错误消息是真实的。在本例中,表示没有名为“x1”的全局变量。所以问问自己“为什么?”。要么根本不创建“x1”变量,要么以非全局的方式创建它

在您的例子中,当您定义x1、y1、x2和y2时,您正在将它们创建为局部变量。这是python在创建变量时的默认行为。最简单的解决方案是将它们声明为全局:

def xaxis(event):
   return (event.x - 1), (event.y - 1) # x1, y1

def yaxis(event):
   return (event.x + 1), (event.y + 1) # x2, y2

def create(event):
   x1, y1 = xaxis(event)
   x2, y2 = yaxis(event)
   w.create_rectangle(x1,y1,x2,y2,fill='Black')
不相关的第二个问题

您的代码中还有一个关于如何进行绑定的问题。考虑这个代码片段:

def xaxis(event):
   global x1, y1
   x1, y1 = (event.x - 1), (event.y - 1)

def yaxis(event):
    global x2, y2
    x2, y2 = (event.x + 1), (event.y + 1)
w.bind(“,yaxis)
w、 绑定(“,创建)
您不是在创建两个绑定,而是在创建一个绑定,然后用另一个绑定覆盖它。但是,您不需要两个绑定。您可以从create函数中调用yaxis函数

使用面向对象的方法 然而,全局变量通常不是问题的最佳解决方案。如果切换到使用面向对象的方法,则可以将坐标存储为对象的属性。下面是一个完整的工作示例:

w.bind("<ButtonRelease-1>", yaxis)
w.bind("<ButtonRelease-1>", create)
将Tkinter作为tk导入
类示例应用程序(tk.tk):
定义初始化(自):
tk.tk.\uuuuu初始化(self)
self.x=self.y=0
self.canvas=tk.canvas(self,宽度=400,高度=400,cursor=“cross”)
self.canvas.pack(side=“top”,fill=“both”,expand=True)
self.canvas.bind(“,self.on_按钮按)
self.canvas.bind(“,self.on\u按钮\u释放)
def on按钮按下(自身,事件):
self.x=event.x
self.y=event.y
def on_按钮_释放(自身,事件):
x0,y0=(self.x,self.y)
x1,y1=(事件x,事件y)
self.canvas.create_矩形(x0,y0,x1,y1,fill=“黑色”)
如果名称=“\uuuuu main\uuuuuuuu”:
app=示例app()
app.mainloop()
拖动鼠标时绘制

如果要在拖动光标时绘制矩形,可以更改程序以在按下按钮时创建矩形。如果为对象指定唯一对象或保存画布,则可以设置鼠标运动事件,以使用画布对象的方法调整当前矩形的坐标。我将把它作为练习留给读者,因为它与所问的问题没有直接关系

解决“全局名称'x1'未定义”问题 调试时的一个好的经验法则是假设错误消息是真实的。在本例中,表示没有名为“x1”的全局变量。所以问问自己“为什么?”。要么根本不创建“x1”变量,要么以非全局的方式创建它

在您的例子中,当您定义x1、y1、x2和y2时,您正在将它们创建为局部变量。这是python在创建变量时的默认行为。最简单的解决方案是将它们声明为全局:

def xaxis(event):
   return (event.x - 1), (event.y - 1) # x1, y1

def yaxis(event):
   return (event.x + 1), (event.y + 1) # x2, y2

def create(event):
   x1, y1 = xaxis(event)
   x2, y2 = yaxis(event)
   w.create_rectangle(x1,y1,x2,y2,fill='Black')
不相关的第二个问题

您的代码中还有一个关于如何进行绑定的问题。考虑这个代码片段:

def xaxis(event):
   global x1, y1
   x1, y1 = (event.x - 1), (event.y - 1)

def yaxis(event):
    global x2, y2
    x2, y2 = (event.x + 1), (event.y + 1)
w.bind(“,yaxis)
w、 绑定(“,创建)
您不是在创建两个绑定,而是在创建一个绑定,然后用另一个绑定覆盖它。但是,您不需要两个绑定。您可以从create函数中调用yaxis函数

使用面向对象的方法 然而,全局变量通常不是问题的最佳解决方案。如果切换到使用面向对象的方法,则可以将坐标存储为对象的属性。下面是一个完整的工作示例:

w.bind("<ButtonRelease-1>", yaxis)
w.bind("<ButtonRelease-1>", create)
将Tkinter作为tk导入
类示例应用程序(tk.tk):
定义初始化(自):
tk.tk.\uuuuu初始化(self)
self.x=self.y=0
self.canvas=tk.canvas(self,宽度=400,高度=400,cursor=“cross”)
self.canvas.pack(side=“top”,fill=“both”,expand=True)
self.canvas.bind(“,self.on_按钮按)
self.canvas.bind(“,self.on\u按钮\u释放)
def on按钮按下(自身,事件):
self.x=event.x
self.y=event.y
def on_按钮_释放(自身,事件):
x0,y0=(self.x,self.y)
x1,y1=(事件x,事件y)
self.canvas.create_矩形(x0,y0,x1,y1,fill=“黑色”)
如果名称=“\uuuuu main\uuuuuuuu”:
app=示例app()
app.mainloop()
拖动鼠标时绘制

如果要在拖动光标时绘制矩形,可以更改t