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)
shell说
Tkinter回调中的异常回溯(最近一次调用最后一次):
文件 “/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py” 第1410行,致电 return self.func(* args)文件“/Users/Leo/Desktop/draw.py”,第22行,在创建 w.create_rectangle(x1,y1,x2,y2,fill ='Black')NameError:未定义全局名称'x1'
它认为create函数无法获取其他函数的坐标...
我是这样做的,因为我以后需要坐标!
我希望你能帮助我.. ;-) 谢谢!
答案 0 :(得分:8)
调试时的一个好的经验法则是假设错误消息说的是实话。在这种情况下,它表示没有名为“x1”的全局变量。所以问问自己“为什么?”。您要么根本不创建“x1”变量,要么创建它不是全局变量。
在您的情况下,当您定义x1,y1,x2和y2时,您将它们创建为局部变量。这是创建变量时python的默认行为。最简单的解决方案是将它们声明为全局:
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("<ButtonRelease-1>", yaxis)
w.bind("<ButtonRelease-1>", create)
您没有创建两个绑定,您正在创建一个绑定,然后用另一个绑定它。但是,您不需要两个绑定。您可以在create函数中调用yaxis函数。
但是,全局变量通常不是问题的最佳解决方案。如果切换到使用面向对象的方法,则可以将坐标存储为对象的属性。这是一个完整的,有效的例子:
import Tkinter as tk
class ExampleApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.x = self.y = 0
self.canvas = tk.Canvas(self, width=400, height=400, cursor="cross")
self.canvas.pack(side="top", fill="both", expand=True)
self.canvas.bind("<ButtonPress-1>", self.on_button_press)
self.canvas.bind("<ButtonRelease-1>", self.on_button_release)
def on_button_press(self, event):
self.x = event.x
self.y = event.y
def on_button_release(self, event):
x0,y0 = (self.x, self.y)
x1,y1 = (event.x, event.y)
self.canvas.create_rectangle(x0,y0,x1,y1, fill="black")
if __name__ == "__main__":
app = ExampleApp()
app.mainloop()
拖动鼠标时绘图
如果要在拖动光标时绘制矩形,可以更改程序以在按下按钮时创建矩形。如果您为对象提供唯一的tag或保存画布id,则可以设置鼠标移动事件以使用画布的coords方法调整当前矩形的坐标宾语。我会将其作为练习留给读者,因为它与被问到的问题没有直接关系。
答案 1 :(得分:1)
您只在本地功能中设置了x1
等(例如xaxis
),因此无法在create
中使用它们。您可以重写这些,以便返回所需的结果:
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')
答案 2 :(得分:0)
您正在将x1,x2 ...的结果存储在局部变量中。退出事件处理函数时,这些值将丢失。您必须使用全局变量或专用对象来管理事件处理程序。我更喜欢第二种解决方案。
另一个问题是你有两个与Button-Release1绑定的函数。我的解决方案不是绑定yaxis并从create中调用它。可以找到一种更清洁的方法:)
见下面的例子。它应该工作:
from Tkinter import *
root=Tk()
class Handler:
def __init__(self, w):
self.w = w
w.bind("<Button-1>", self.xaxis)
#w.bind("<ButtonRelease-1>", self.yaxis)
w.bind("<ButtonRelease-1>", self.create)
def xaxis(self, event):
self.x1, self.y1 = (event.x - 1), (event.y - 1)
def yaxis(self, event):
self.x2, self.y2 = (event.x + 1), (event.y + 1)
def create(self, event):
self.yaxis(event)
self.w.create_rectangle(self.x1,self.y1,self.x2,self.y2,fill='Black')
w = Canvas(root, width=200, height=200)
w.config(cursor='cross')
w.pack(expand=YES, fill=BOTH)
Handler(w)
root.mainloop()