使用鼠标在 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()
所以目前我正在开发一个程序,允许折纸艺术家使用这个程序在他们的计算机上创建折痕图案。到目前为止,我有一个在 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()