gpt4 book ai didi

python - 如何移动 Canvas 多边形?

转载 作者:行者123 更新时间:2023-12-05 07:57:12 29 4
gpt4 key购买 nike

我想在 python tkinter 中移动对象,特别是多边形。问题出在 is_click 函数中。我似乎无法弄清楚如何确定我是否单击了该对象。代码还没有 100% 完成,移动仍然需要完成,但我现在需要弄清楚这一点。我也有类似的类,您可以在其中移动圆和矩形,其中 is_click 函数正在运行,但由于多边形具有 3 到 4 个坐标,因此有点复杂。自己运行这些类,看看它们在做什么。

我的多边形代码:

import tkinter

class Polygon:

def __init__(self, ax, ay, bx, by, cx, cy, dx=None, dy=None, color=None):
self.ax = ax
self.ay = ay
self.bx = bx
self.by = by
self.cx = cx
self.cy = cy
self.dx = dx
self.dy = dy
self.color = color

def is_click(self, event_x, event_y):
pass

def paint(self, g):
self.g = g
if self.dx is None:
self.id = self.g.create_polygon(self.ax,self.ay,
self.bx,self.by,
self.cx,self.cy,
fill=self.color)
else:
self.id = self.g.create_polygon(self.ax,self.ay,
self.bx,self.by,
self.cx,self.cy,
self.dx,self.dy,
fill=self.color)

def move(self, d_ax=0, d_ay=0, d_bx=0, d_by=0, d_cx=0, d_cy=0, d_dx=None, d_dy=None):
if d_dx is None:
self.ax += d_ax
self.ay += d_ay
self.bx += d_bx
self.by += d_by
self.cx += d_cx
self.cy += d_cy
self.g.move(self.id, d_ax, d_ay, d_bx, d_by, d_cx, d_cy)
else:
self.ax += d_ax
self.ay += d_ay
self.bx += d_bx
self.by += d_by
self.cx += d_cx
self.cy += d_cy
self.dx += d_dx
self.dy += d_dy
self.g.move(self.id, d_ax, d_ay, d_bx, d_by, d_cx, d_cy, d_dx, d_dy)


class Tangram:

def __init__(self):
self.array = []
self.g = tkinter.Canvas(width=800,height=800)
self.g.pack()

#all objects
self.add(Polygon(500,300,625,175,750,300, color='SeaGreen'))
self.add(Polygon(750,50,625,175,750,300, color='Tomato'))
self.add(Polygon(500,175,562.6,237.5,500,300, color='SteelBlue'))
self.add(Polygon(500,175,562.5,237.5,625,175,562.5,112.5, color='FireBrick'))
self.add(Polygon(562.5,112.5,625,175,687.5,112.5, color='DarkMagenta'))
self.add(Polygon(500,50,500,175,625,50, color='Gold'))
self.add(Polygon(562.5,112.5,687.5,112.5,750,50,625,50, color='DarkTurquoise'))
#end of all objects

self.g.bind('<Button-1>', self.event_move_start)

def add(self, Object):
self.array.append(Object)
Object.paint(self.g)

def event_move_start(self, event):
ix = len(self.array) - 1
while ix >= 0 and not self.array[ix].is_click(event.x, event.y):
ix -= 1
if ix < 0:
self.Object = None
return
self.Object = self.array[ix]
self.ex, self.ey = event.x, event.y
self.g.bind('<B1-Motion>', self.event_move)
self.g.bind('<ButtonRelease-1>', self.event_release)

def event_move(self):
pass

def event_release(self):
pass

Tangram()

以及圆形和矩形移动的代码:

import tkinter, random

class Circle:
def __init__(self, x, y, r, color='red'):
self.x = x
self.y = y
self.r = r
self.color = color

def is_click(self, x, y):
return (self.x-x)**2+(self.y-y)**2 < self.r**2

def paint(self, g):
self.g = g
self.id = self.g.create_oval(self.x-self.r,self.y-self.r,
self.x+self.r,self.y+self.r,
fill=self.color)

def move(self, dx=0, dy=0):
self.g.delete(self.id)
self.x += dx
self.y += dy
self.paint(self.g)

class Rectangle:
def __init__(self, x, y, width, height, color='red'):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color

def is_click(self, x, y):
return self.x<=x<self.x+self.width and self.y<=y<self.y+self.height

def paint(self, g):
self.g = g
self.id = self.g.create_rectangle(self.x,self.y,
self.x+self.width,self.y+self.height,
fill=self.color)

def move(self, dx=0, dy=0):
self.x += dx
self.y += dy
self.g.move(self.id, dx, dy)

class Program:
def __init__(self):
self.array = []
self.g = tkinter.Canvas(bg='white', width=400, height=400)
self.g.pack()
for i in range(20):
if random.randrange(2):
self.add(Circle(random.randint(50, 350),random.randint(50, 350), 20, 'blue'))
else:
self.add(Rectangle(random.randint(50, 350),random.randint(50, 350), 40, 30))
self.g.bind('<Button-1>', self.event_move_start)

def add(self, Object):
self.array.append(Object)
Object.paint(self.g)

def event_move_start(self, e):
ix = len(self.array)-1
while ix >= 0 and not self.array[ix].is_click(e.x, e.y):
ix -= 1
if ix < 0:
self.Object = None
return
self.Object = self.array[ix]
self.ex, self.ey = e.x, e.y
self.g.bind('<B1-Motion>', self.event_move)
self.g.bind('<ButtonRelease-1>', self.event_release)

def event_move(self, e):
self.Object.move(e.x-self.ex, e.y-self.ey)
self.ex, self.ey = e.x, e.y

def event_release(self, e):
self.g.unbind('<B1-Motion>')
self.g.unbind('<ButtonRelease-1>')
self.Object = None

Program()

最佳答案

这不是您问题的完整答案,但评论太长了。我会集中考虑的一种方法是更改​​/修改您的代码,以便它使用 find_closes 方法。使用此方法,您可以非常轻松地确定单击了哪个小部件(即多边形)。作为概念的快速证明,您可以在 Tangram 和 ploygon 类中进行以下更改:

def event_move_start(self, event):
ix = len(self.array) - 1
while ix >= 0 and not self.array[ix].is_click(event, self.g, event.x, event.y): # add event and canvas to argumetns

在多边形中:

def is_click(self, event, g, event_x, event_y):
widget_id = event.widget.find_closest(event.x, event.y)
print(widget_id)
g.move(widget_id, 1, 1) # just dummy move for a clicked widget
pass

这将打印点击的小部件/多边形的 ID 并稍微移动点击的多边形。这可用于选择单击了哪个对象,有了这个 id 对象,您就可以进行移动或其他操作。

附注我用来测试它的完整代码是 here .

希望这对您有所帮助。

关于python - 如何移动 Canvas 多边形?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27735649/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com