Skip to main content
 首页 » 编程设计

python之单击鼠标绘制矩形 [Python]

2025年05月04日14duanxz

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) 

外壳说

Exception in Tkinter callback Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", line 1410, in call return self.func(*args) File "/Users/Leo/Desktop/draw.py", line 22, in create w.create_rectangle(x1,y1,x2,y2,fill='Black') NameError: global name 'x1' is not defined

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

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

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

请您参考如下方法:

解决“global name 'x1' is not defined”问题

调试时的一个好的经验法则是假定错误消息是真实的。在这种情况下,它表示没有名为“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) 

一个不相关的第二个问题

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

w.bind("<ButtonRelease-1>", yaxis) 
w.bind("<ButtonRelease-1>", create) 

您不是在创建两个绑定(bind),而是在创建一个绑定(bind),然后用另一个覆盖它。但是,您不需要两个绑定(bind)。您可以从 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或保存 Canvas id ,你可以设置一个鼠标移动事件来调整当前矩形的坐标,使用 coords Canvas 对象的方法。我将把它留给读者作为练习,因为它与提出的问题没有直接关系。