Python tkinter 画布 动态创建线条

2 投票
2 回答
6807 浏览
提问于 2025-04-17 16:55

我想做的是让用户在画布上点击一个地方,然后再点击另一个地方,这样就能在这两个点之间画一条直线。我刚接触TKinter,经过一些搜索后,发现很难找到一个明确的解决方案。

我想到的方式是,应该有一个点击事件,这个事件能获取到鼠标在画布上的坐标,然后还有一个释放事件,这个事件也能获取到这些坐标,这样就能在它们之间画出一条线。这条线需要是一个对象,以便我可以通过另一个按钮在某个时候把它删除,但这又是另一个问题了。

如果有人能提供帮助,或者分享一些可能有用的文章或教程,我将非常感激。

2 个回答

3

这看起来对我来说很简单。

你可以查看一下关于Canvas的文档,地址在这里: http://effbot.org/tkinterbook/canvas.htm

还有关于事件的文档在这里: http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm

然后,你只需要输入一些代码,比如这样—— 这个类比一个简单的“你好,世界”还要复杂, 其实用两个全局变量就能写出更简单的代码:

from Tkinter import Canvas, Tk, mainloop
w = Tk()
c = Canvas(w)
c.pack()

class DrawLines(object):
    def __init__(self, canvas):
        self.canvas = canvas
        self.start_coords = None
        self.end_coords = None
    def __call__(self, event):
        coords = event.x, event.y
        if not self.start_coords:
            self.start_coords = coords
            return
        self.end_coords = coords
        self.canvas.create_line(self.start_coords[0],
                                self.start_coords[1],
                                self.end_coords[0],
                                self.end_coords[1])
        self.start_coords = self.end_coords

c.bind("<Button-1>", DrawLines(c))

mainloop()
8

你只需要把 "<Button-1>""<ButtonRelease-1>" 这两个事件绑定到画布上就可以了:

from Tkinter import Tk, Canvas

start = None

def onclick_handler(event):
    global start
    start = (event.x, event.y)

def onrelease_handler(event):
    global start
    if start is not None:
        x = start[0]
        y = start[1]
        event.widget.create_line(x, y, event.x, event.y)
        start = None

master = Tk()
canvas = Canvas(master, width=200, height=200)
canvas.bind("<Button-1>", onclick_handler)
canvas.bind("<ButtonRelease-1>", onrelease_handler)
canvas.pack()
master.mainloop()

我个人不太喜欢使用全局变量,把所有的控件和相关的功能放在一个类里会更整洁。不过,作为一个例子,我觉得这样已经足够清楚了。

撰写回答