单击鼠标绘制矩形[Python]

Leo*_*Leo 1 python drawing tkinter rectangles

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)
Run Code Online (Sandbox Code Playgroud)

壳说

Tkinter回调中的异常回溯(最近一次调用最后一次):
文件"/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py",第1410行,在call return self中. func(*args)文件"/Users/Leo/Desktop/draw.py",第22行,创建w.create_rectangle(x1,y1,x2,y2,fill ='Black')NameError:全局名称'x1'是没有定义的

它认为创建函数无法获取其他函数的坐标...

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

我希望你能帮帮我.. ;-)谢谢!

Bry*_*ley 8

解决"全局名称'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)
Run Code Online (Sandbox Code Playgroud)

一个无关的第二个问题

您的代码中还有另一个问题,即如何进行绑定.请考虑以下代码段:

w.bind("<ButtonRelease-1>", yaxis)
w.bind("<ButtonRelease-1>", create)
Run Code Online (Sandbox Code Playgroud)

您没有创建两个绑定,您正在创建一个绑定,然后用另一个绑定它.但是,您不需要两个绑定.您可以在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()
Run Code Online (Sandbox Code Playgroud)

拖动鼠标时绘图

如果要在拖动光标时绘制矩形,可以更改程序以在按下按钮时创建矩形.如果要么为对象提供唯一标记或保存画布ID,则可以设置鼠标移动事件以使用画布对象的coords方法调整当前矩形的坐标.我会将其作为练习留给读者,因为它与被问到的问题没有直接关系.