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

标签 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)

外壳说

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 对象的方法。我将把它留给读者作为练习,因为它与提出的问题没有直接关系。

关于python - 单击鼠标绘制矩形 [Python],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12837575/

相关文章:

Java Swing/AWT - 使用上下文菜单绘制对象

python - 如何在 `tk.Label`的值发生变化时自动更新 `tk.Scale`?

python - 用python gtk键盘中断?

python - pytesseract,Windows 错误 : [Error 2] The system cannot find the file specified

python - (Python) socket.gaierror : [Errno 11001] getaddrinfo failed

python - 类型错误 : 'NoneType' object is not iterable WTForms FieldSelect

表单加载时 Java GUI 绘制并填充矩形

水平 ScrollView 上的android绘图线

python - 我该如何将StringVar()放入StringVar()中?

python - 如何禁用对文本小部件的输入但允许编程输入?