<B1-Motion> 绑定在 Tkinter 中没有响应

<B1-Motion> binding is unresponsive in Tkinter

我一直在努力学习更多关于 tkinter 中的 Canvas() 小部件的信息,所以我决定构建一个简单的绘画应用程序来练习。

为此,我创建了一个canvas并将其绑定到"<B1-Motion>",但是当我拖动鼠标太快时它变得无响应。

这是一个代码示例:

from tkinter import *


class Paint:
    def __init__(self, root):
        self.root = root

        self.current_x = None
        self.current_y = None

        self.brush_size = 10
        self.brush_color = "black"

    def create_widgets(self):
        # Creating the canvas
        self.canvas = Canvas(self.root, width=1000, height=1000)
        self.canvas.grid(row=0, column=0, sticky="nsew")

        # Setting up bindings for the canvas.
        self.canvas.bind("<Button-1>", self.setup_coords)
        self.canvas.bind("<B1-Motion>", self.drag)

    def setup_coords(self, e):
        # Reset the starting points to the current mouse position
        self.current_x = e.x
        self.current_y = e.y

    def drag(self, e):
        # Create an oval that's size is the same as brush_size
        oval = self.canvas.create_oval(self.current_x, self.current_y, self.current_x+self.brush_size, self.current_y+self.brush_size, fill=self.brush_color)

        # Set the variables values to the current position of the mouse, so that the oval gets drawn correctly on the next call.
        self.current_x = e.x
        self.current_y = e.y


def main():
    root = Tk()
    root.geometry("1000x1000")
    p = Paint(root)
    p.create_widgets()
    mainloop()

if __name__ == '__main__':
    main()

在这里,当我慢慢拖动鼠标时,一切正常:

但是一旦我开始快速拖动,绑定就不会被及时调用,只会绘制几个圆圈:

我在这里做的事情效率低下吗?有什么办法可以解决这个问题吗?

如果有人能帮助我,那就太好了。提前致谢。

更新:

我尝试了 acw1668 的建议,即画线而不是圆并将其宽度设置为画笔大小:

from tkinter import *


class Paint:
    def __init__(self, root):
        self.root = root

        self.current_x = None
        self.current_y = None

        self.brush_size = 50
        self.brush_color = "black"

    def create_widgets(self):
        # Creating the canvas
        self.canvas = Canvas(self.root, width=1000, height=1000)
        self.canvas.grid(row=0, column=0, sticky="nsew")

        # Setting up bindings for the canvas.
        self.canvas.bind("<Button-1>", self.setup_coords)
        self.canvas.bind("<B1-Motion>", self.drag)

    def setup_coords(self, e):
        # Reset the starting points to the current mouse position
        self.current_x = e.x
        self.current_y = e.y

    def drag(self, e):
        # Create an oval that's size is the same as brush_size
        oval = self.canvas.create_line(self.current_x, self.current_y, e.x, e.y, width=self.brush_size, fill=self.brush_color)

        # Set the variables values to the current position of the mouse, so that the oval gets drawn correctly on the next call.
        self.current_x = e.x
        self.current_y = e.y


def main():
    root = Tk()
    root.geometry("1000x1000")
    p = Paint(root)
    p.create_widgets()
    mainloop()

if __name__ == '__main__':
    main()

但是,当我增加画笔尺寸时,仍然存在一些不需要的间隙:

有任何修复吗?

对于 well-connected 行,在创建行时将集合 capstyle 设置为 round

查看 this canvas tutorial 了解更多详情。

我熟悉的几乎所有绘图库都支持不同的线端(“caps”)样式,以及线连接(“joins”)样式。

另请注意,您可以使用 create_line 绘制二次 Bézier 样条曲线或三次样条曲线。