使用鼠标在 python 上使用网格在 tkinter canvas 上绘制直线

Drawing straight lines on a tkinter canvas with Grid on python with mouse

所以目前我正在开发一个程序,允许折纸艺术家使用这个程序在他们的计算机上创建折痕图案。到目前为止,我有一个在 canvas 上绘制网格并允许用户绘制自由线的程序,但是,我要求用户能够绘制直线,但我不确定如何调整此代码因此用户可以绘制直线而不是自由曲线。到目前为止,这是我的代码:

from tkinter import *

Mouse = "up"
xold, yold = None, None
def DrawGrid(drawing_area, line_distance):

   for x in range(line_distance,600,line_distance):
       drawing_area.create_line(x, 0, x, 600, fill="#d3d3d3")

   for y in range(line_distance,600,line_distance):
       drawing_area.create_line(0, y, 600, y, fill="#d3d3d3")

def main():
    root = Tk()
    drawing_area = Canvas(root, width=600, height=600, bg='white')
    drawing_area.pack()
    DrawGrid(drawing_area, 10)
    drawing_area.bind("<Motion>", motion)
    drawing_area.bind("<ButtonPress-1>", Mousedown)
    drawing_area.bind("<ButtonRelease-1>", Mouseup)

    root.mainloop()

def Mousedown(event):
    global Mouse
    Mouse = "down"         

def Mouseup(event):
    global Mouse, xold, yold
    Mouse = "up"
    xold = None           
    yold = None

def motion(event):
    if Mouse == "down":
        global xold, yold

    if xold is not None and yold is not None:
        event.widget.create_line(xold,yold,event.x,event.y,smooth=TRUE)

    xold = event.x
    yold = event.y


main()

谢谢, Mistry27

我的解决方案是一次只让用户画一条线。也就是说,当鼠标移动时,您不会继续创建新行。相反,修改现有行。

例如,您可以这样设置,当用户单击然后移动鼠标时,无论鼠标在什么位置,从他们单击的位置到当前位置只画一条线。这将迫使线始终尽可能笔直。

我从您的代码开始,并尽可能少地进行更改以展示其工作原理。如果单击、拖动、单击、拖动、单击等,每次单击之间只会绘制一条线段。如果要开始一个与当前行完全断开的新行,请按 escape 键。

在代码中,变量current包含当前正在绘制的线的id。当您按 escape 时,它会重置为 None。每当您单击鼠标时,都会从 current 的末尾或当前鼠标位置开始新的一行。在运动过程中,我们只是重置当前行的端点。

from tkinter import *

current = None

def DrawGrid(drawing_area, line_distance):

   for x in range(line_distance,600,line_distance):
       drawing_area.create_line(x, 0, x, 600, fill="#d3d3d3")

   for y in range(line_distance,600,line_distance):
       drawing_area.create_line(0, y, 600, y, fill="#d3d3d3")

def main():
    root = Tk()
    drawing_area = Canvas(root, width=600, height=600, bg='white')
    drawing_area.pack()
    DrawGrid(drawing_area, 10)
    drawing_area.bind("<Escape>", reset)
    drawing_area.bind("<Motion>", motion)
    drawing_area.bind("<ButtonPress-1>", Mousedown)

    root.mainloop()

def reset(event):
    global current
    current = None

def Mousedown(event):
    global current

    event.widget.focus_set()  # so escape key will work

    if current is None:
        # the new line starts where the user clicked
        x0 = event.x
        y0 = event.y

    else:
        # the new line starts at the end of the previously
        # drawn line
        coords = event.widget.coords(current)
        x0 = coords[2]
        y0 = coords[3]

    # create the new line
    current = event.widget.create_line(x0, y0, event.x, event.y)

def motion(event):
    if current:
        # modify the current line by changing the end coordinates
        # to be the current mouse position
        coords = event.widget.coords(current)
        coords[2] = event.x
        coords[3] = event.y

        event.widget.coords(current, *coords)

main()