如何从锚点旋转 tkinter 画布小部件?

Posted

技术标签:

【中文标题】如何从锚点旋转 tkinter 画布小部件?【英文标题】:How can you rotate a tkinter canvas widget from an anchor point? 【发布时间】:2021-08-23 10:27:48 【问题描述】:

感谢您查看我的问题。

所以我想知道您是否可以从锚点旋转画布对象。例如,一个正方形在 0,100,锚点在 0,0,然后正方形从锚点旋转。如果你有办法做到这一点,请解释它是如何工作的以及为什么,我将不胜感激。

【问题讨论】:

这能回答你的问题吗? Rotating a Square on Tkinter Canvas。你可以在你的代码中实现类似的东西。 @willywillycow 有几点需要理解。首先,您不能为此使用内置命令create_rectangle。因为所有 4 个点都需要调整,而内置为您提供了两个点。背后的数学使用简单地 trigonometric function 还注意,如果你想从一个点旋转,比如中间你需要translate。您可以通过计算点或在中间设置画布的 thr oringin 来实现这一点,这意味着使用滚动区域。 另见我对How to rotate a polygon?的回答 @willywillycow 你能告诉我你的代码吗? @Atlas435 抱歉找不到原文件 【参考方案1】:

我强烈推荐 martineaus 回答 here

import tkinter as tk
import math
from itertools import islice

def draw_square(x,y,w,h):
    lu = (x,y)#left upper corner
    ru = (x+w,y)#right upper corner
    rb = (x+w,y+h)#right bottom corner
    lb = (x,y+h)#left bottom corner
    square = cnvs.create_polygon(lu,ru,rb,lb)
#using polygon for simple fill and getting the dots
    return square #return square_id

def pair_it(itr):#function to chunk list into x,y pairs
    itr = iter(itr)
    return iter(lambda:tuple(islice(itr,2)),())

def rotate_polygon(_id,angle):
    pns = cnvs.coords(_id)
    xy = list(pair_it(pns))
    mid_x=sum([p[0] for p in xy])/len(xy)#sumerize x and divide through len
    mid_y=sum([p[1] for p in xy])/len(xy)#sumerize y and divide through len
    # I was stealen it from martineau, since my bbox method failed
##    bbox = cnvs.bbox(square_id)
##    r1 = (bbox[2]-bbox[0])/2
##    r2 = (bbox[3]-bbox[1])/2
##    mid_x,mid_y=bbox[0]+r1,bbox[1]+r2
##    worked for an amount of rotations but messed up till it got stable again
    radians=angle*math.pi/180
    new_coords = []
    for edge in xy:
        edx,edy = edge[0]-mid_x,edge[1]-mid_y#here it "translates the surface" to mid point
        x = edx*math.cos(radians)-edy*math.sin(radians)+mid_x#here we translate back
        y = edx*math.sin(radians)+edy*math.cos(radians)+mid_y#here we translate back
        new_coords.extend((x,y))
    cnvs.coords(_id,new_coords)
    root.after(1,rotate_polygon,_id,angle)

root = tk.Tk()
cnvs = tk.Canvas(root)
square_I = draw_square(150,50, 100,200)
cnvs.itemconfig(square_I, fill='red')
root.bind('<Button-1>',lambda e:rotate_polygon(square_I,20))
cnvs.pack()

root.mainloop()

【讨论】:

以上是关于如何从锚点旋转 tkinter 画布小部件?的主要内容,如果未能解决你的问题,请参考以下文章

简单的 Qt 小部件来绘制线条和形状(如 tkinter 画布)?

如何同时移动两个 tkinter 小部件但异步?

如何使用 tkinter Canvas 小部件制作按钮?

tkinter canvas create_window

tkinter - 加权画布不填充空白空间

使用透明背景、ttk 框架背景颜色配置 tkinter/ttk 小部件?