【问题标题】:How to enlarge and reduce an already drawn lines, using certain buttons?如何使用某些按钮放大和缩小已经绘制的线条?
【发布时间】:2021-06-08 16:02:03
【问题描述】:

假设我有以下用 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)

我已经尝试过使用较小的图像,但它不起作用。

def reduced():
    line_reduced = ()
    for i in newline:
        line_reduced += (i/2,)
        canvas.delete('all')
        canvas.create_line(line_reduced, fill='red', width=4, tags='foto1')

我需要添加它,以便可以使用两个键缩小或放大此形状。因此,图像将保持不变(形状),只会缩小/放大。

如果有任何建议,我将不胜感激。

【问题讨论】:

  • 你的标题提到了一张图片,但没有一个代码显示图片。您是在询问图像,还是询问其他画布类型(线条、矩形等)?
  • for i in newline 无效,因为newline 是一个函数。
  • 你可以使用canvas.scale()函数来调整线条的大小。
  • @BryanOakley 我指的是其他画布类型,例如本例中的线条。谢谢提醒,我已经改过了。
  • @acw1668 ~ 我不确定你是在耍流氓还是认真的。我几乎肯定发帖人在问scale 是否可以通过按钮调用。 :D

标签: python tkinter button


【解决方案1】:

如果您想在画布上缩放一堆线条,您可以使用scale,但是添加到canvas 的所有新内容也必须进行缩放,否则它会开始变得奇怪。你可能真正需要的是数学。特别是这个等式N = Scale * (N - Pn) + Pn。下面是一个简单的绘图界面,带有您请求的按钮。主要它只是一堆存储点和创建线。您感兴趣的部分是这一行:

line[n] = scale * (point - center) + center.

在我的示例代码中,行存储为[x1, y1, x2, y2](行的开头和结尾)。 line 将引用这样的列表。 line[n] 引用该列表中的每个 xy 值,因为 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 距离center 100
现在x1 距离center 200 倍
x1 距离中心scale 比以前远了几倍

代码:

import tkinter as tk
root = tk.Tk()

canvas = tk.Canvas(root, width=800, height=600, bg='white')
canvas.pack()

#for storing line canvas ids and line coordinates
line_ids, lines = [], [] 

#line properties ~ width and fill
global w, f
w, f = 2, 'red'

#draw a line
def draw(event):
    if event.type is tk.EventType.ButtonPress:
        #store line start coordinate
        lines.append([event.x, event.y])
        #create a dummy line
        line_ids.append(canvas.create_line(*lines[-1], *lines[-1], fill=f, width=w))
    elif event.type is tk.EventType.Motion:
        #keep deleting and redrawing the current line til you release the mouse
        canvas.delete(line_ids.pop())
        line_ids.append(canvas.create_line(*lines[-1], event.x, event.y, fill=f, width=w))
    elif event.type is tk.EventType.ButtonRelease:
        #append the end coordinate to the last line
        lines[-1] += [event.x, event.y]

#add mouse events to canvas for drawing functionality
for event in ['<B1-Motion>', '<Button-1>', '<ButtonRelease-1>']:
    canvas.bind(event, draw) 

#scale lines
def scale_lines(scale): 
    #remove all canvas references to lines   
    canvas.delete("all")
    line_ids = []
    #traverse every line
    for i, line in enumerate(lines):
        #traverse every point in THIS line
        for n, point in enumerate(line):
            #toggle between center x and center y depending if point is an x or y
            center = canvas.winfo_width()/2 if not n%2 else canvas.winfo_height()/2
            #scale this point
            line[n] = scale * (point - center) + center
        #create a new line with scaled points
        line_ids.append(canvas.create_line(*line, fill=f, width=w))    

#increase/decrease buttons    
tk.Button(root, command=lambda: scale_lines(.5), text='decrease').pack(side='left')
tk.Button(root, command=lambda: scale_lines(2), text='increase').pack(side='left')

root.mainloop()

【讨论】:

  • 非常感谢。这真的很有帮助,现在我终于明白了!
猜你喜欢
  • 1970-01-01
  • 2013-01-21
  • 1970-01-01
  • 2017-12-05
  • 2023-01-25
  • 2023-03-24
  • 1970-01-01
  • 2020-04-25
  • 1970-01-01
相关资源
最近更新 更多