在tkinter画布上绘制直线与python上的网格与鼠标

时间:2016-11-29 23:06:00

标签: canvas tkinter python-3.4

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

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

1 个答案:

答案 0 :(得分:0)

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

例如,你可以这样做,以便当用户点击然后移动鼠标时,无论鼠标在哪里,只会从他们点击到当前位置的位置绘制一条线。这将迫使线条始终尽可能地直线。

我开始使用您的代码并尽可能少地进行更改以显示其可能如何工作。如果单击,拖动,单击,拖动,单击等,它将在每次单击之间仅绘制一个线段。如果要开始与当前行完全断开的新行,请按 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()