Python 如何使用某些按钮放大和缩小已绘制的线条?

Python 如何使用某些按钮放大和缩小已绘制的线条?,python,tkinter,button,Python,Tkinter,Button,假设我用Python中的Tkinter编写了以下程序,您可以在其中单击以绘制任何形状 import tkinter canvas = tkinter.Canvas(width=500, height=500, bg='white') canvas.pack() line = () def draw(): canvas.delete('all') if len(line) >= 4: canvas.create_line(line, fill='red',

假设我用Python中的Tkinter编写了以下程序,您可以在其中单击以绘制任何形状

import tkinter
canvas = tkinter.Canvas(width=500, height=500, bg='white')
canvas.pack()

line = ()
def draw():
    canvas.delete('all')
    if len(line) >= 4:
        canvas.create_line(line, fill='red', width=2)
def newline(coordinates):
    global line
    line = line + (coordinates.x, coordinates.y)
    draw()
canvas.bind('<Button-1>', newline)
我将需要添加它,这样这个形状就可以减少或扩大使用两个关键点。因此,图像将保持不变(形状),只会缩小/放大


我将非常感谢您的建议。

如果您试图在画布上缩放一组线条,您可以使用
缩放
,但是您添加到
画布
的所有新内容也必须缩放,否则会变得奇怪。你可能真正需要的是数学。具体来说,这个方程
N=Scale*(N-Pn)+Pn
。下面是一个简单的绘图界面,带有您要求的按钮。基本上,它只是一堆存储点和创建线。您感兴趣的部分是这一行:

line[n]=比例*(点-中心)+中心

在我的示例代码(行的开头和结尾)中,行存储为
[x1,y1,x2,y2]
<代码>行将引用这样的列表<代码>行[n]引用该列表中的每个
x
y
值,因为
n
是递增的。也就是说:

line[n]=scale*(point-center)+center
实际上是说从点中减去中心,乘以比例数,然后再将中心加回去,这样缩放点与中心的缩放距离不变

让我们再看一遍,让你明白

黑板:

x1     = 100
center = 200
scale  = 2

formula: x1 = scale * (x1 - center) + center
1      : x1 = 2 * (100 - 200) + 200
2      : x1 = 2 * (-100) + 200
3      : x1 = -200 + 200
4      : x1 = 0

旧的
x1
距离
中心100

现在
x1
距离
中心200

x1
scale
距离中心的距离以前的倍

代码:

将tkinter作为tk导入
root=tk.tk()
canvas=tk.canvas(根,宽度=800,高度=600,bg='white')
canvas.pack()
#用于存储线条画布ID和线条坐标
行标识,行=[],[]
#线条属性~宽度和填充
全球w,f
w、 f=2,‘红色’
#划一条线
def提取(事件):
如果event.type是tk.EventType.button,请按:
#存储线起始坐标
line.append([event.x,event.y])
#创建虚拟线
行\u id.append(canvas.create\u行(*行[-1],*行[-1],填充=f,宽度=w))
elif event.type是tk.EventType.Motion:
#继续删除并重新绘制当前行,直到释放鼠标
canvas.delete(line_id.pop())
行\u id.append(canvas.create\u行(*line[-1],event.x,event.y,fill=f,width=w))
elif event.type为tk.EventType.ButtonRelease:
#将端点坐标附加到最后一行
行[-1]+=[event.x,event.y]
#将鼠标事件添加到画布以实现绘图功能
对于['',''中的事件:
canvas.bind(事件、绘制)
#刻度线
def刻度线(刻度):
#删除对行的所有画布引用
canvas.delete(“全部”)
行_id=[]
#横穿每一条线
对于i,枚举中的行(行):
#穿过这条线的每一点
对于n,枚举中的点(行):
#根据点是x还是y在中心x和中心y之间切换
中心=canvas.winfo_width()/2如果不是n%2,则为canvas.winfo_height()/2
#衡量这一点
线[n]=标度*(点-中心)+中心
#创建具有缩放点的新线
行\u id.append(canvas.create\u行(*行,填充=f,宽度=w))
#增加/减少按钮
按钮(根,命令=lambda:scale_line(.5),text='decrease').pack(side='left')
按钮(根,命令=lambda:scale_line(2),text='increase').pack(side='left'))
root.mainloop()

标题中提到了图像,但没有一个代码显示图像。您是在询问图像,还是在询问其他画布类型(线条、矩形等)?
for i in newline
无效,因为
newline
是一个函数。您可以使用
canvas.scale()
函数来调整线条的大小。@BryanOakley我指的是其他画布类型,如本例中的线条。谢谢你的警告,我已经改变了这个。@acw1668~我不确定你是在开玩笑还是非常认真。我几乎可以肯定海报是在问,是否可以通过按钮调用
scale
:谢谢你。这真的很有帮助,现在我终于明白了!
x1     = 100
center = 200
scale  = 2

formula: x1 = scale * (x1 - center) + center
1      : x1 = 2 * (100 - 200) + 200
2      : x1 = 2 * (-100) + 200
3      : x1 = -200 + 200
4      : x1 = 0