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)
外壳说
例外的Tkinter回调回溯(最近通话最后一个):
文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py”,线1410,在调用返回self.func(*参数)文件“/用户/狮子座/桌面/ draw.py” 22行,在创建w.create_rectangle(X1,Y1,X2,Y2,填补= '黑')NameError:不定义的全局名称 'X1'
它认为建立功能不能够得到的其他功能的坐标...
我就是这么做的,因为我以后需要的坐标!
我希望你能帮助我.. ;-)谢谢!
解决“全球名‘X1’没有定义”的问题
调试时一个好的经验法则是假设错误消息说的是实话。 在这种情况下,它是说,没有名为“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)
你是不是创建两个绑定,要创建一个,然后用另一个覆盖它。 你不需要两个绑定,但是。 您可以在创建函数中调用你y轴的功能。
使用面向对象的方法
然而,全局变量通常不是一个问题的最佳解决方案。 如果您切换到使用面向对象的方法,那么你可以将坐标存储为一个对象的属性。 下面是一个完整,工作示例:
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()
作为绘制拖动鼠标
如果你想为你拖动光标以绘制矩形,你可以改变程序来创建按钮按矩形。 如果你要么给对象的唯一标签或保存画布ID ,您可以设置鼠标移动事件来调整使用当前矩形的坐标COORDS画布对象的方法。 我会离开,作为一个练习留给读者,因为它不直接关系到被问的问题。
您只设置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')
You are storing results of x1, x2 ... in local variables. These values are lost when you exit the event handler function. You must use global vars or a dedicated object for managing event handlers. I would prefer the 2nd solution.
Another issue is that you have two functions bound with Button-Release1. My solution is not to bound yaxis and to call it from create. A cleaner approach can be found :)
See example below. It should work:
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()