[英]How to move multiple objects together in tkinter canvas?
我試圖用鼠標拖動 Ndrop 在 canvas 周圍移動一些帶有文本的矩形。 我使用 find_overlapping 到要移動的 select 矩形。 這意味着最初作為 class object Rect 的一部分創建的文本不會移動。 有沒有辦法修改我的代碼以移動 class object 中的所有對象,或者也許使用 ID_CFDE6331BD46EB2AC96F8911 找到 class ZA8CFDE6331BD46EB2AC96F8911
矩形上的文本可以相同,如示例所示。 使用隨機標簽標記 class object 中的所有元素以將它們組合在一起是我的第一個想法,但使用 find_ovelapping 檢索此類標簽信息並未成功。
import tkinter as tk
root=tk.Tk()
PAB=tk.Canvas(width=400, height=400)
#checks if a certain canvas object has a certain tag
def hastag(tag, id):
if any(tag in i for i in PAB.gettags(id)):return True
else:return False
class Rect:
def __init__(self, x1, y1, name):
rec = PAB.create_rectangle(x1,y1,x1+40,y1+40, fill='#c0c0c0', tag=('movable', name))
text = PAB.create_text(x1+20,y1+20, text=name)
#mouse click find object to move
def get_it(event):
delta=5
global cur_rec
for i in PAB.find_overlapping(event.x-delta, event.y-delta, event.x+delta, event.y-delta):
if hastag('movable', i):
cur_rec = i
PAB.bind('<Button-1>', get_it)
#mouse movement moves object
def move_it(event):
xPos, yPos = event.x, event.y
xObject, yObject = PAB.coords(cur_rec)[0],PAB.coords(cur_rec)[1]
PAB.move(cur_rec, xPos-xObject, yPos-yObject)
PAB.bind('<B1-Motion>', move_it)
#test rects
bob = Rect(20,20,'Bob')
rob = Rect(80,80,'Rob')
different_bob = Rect(160,160,'Bob')
PAB.pack()
root.mainloop()
謝謝。 如果需要任何澄清,我很樂意提供幫助。
更好的方法是對要一起移動的所有項目使用相同的標簽,因此在您的情況下,矩形和文本都必須具有相同的標簽。
import tkinter as tk
root=tk.Tk()
PAB=tk.Canvas(width=400, height=400, bg="gray")
class Rect:
def __init__(self, x1, y1, name):
tag = f"movable{id(self)}"
rec = PAB.create_rectangle(x1,y1,x1+40,y1+40, fill='#c0c0c0', tag=(tag, ))
text = PAB.create_text(x1+20,y1+20, text=name, tag=(tag,))
def in_bbox(event, item): # checks if the mouse click is inside the item
bbox = PAB.bbox(item)
return bbox[0] < event.x < bbox[2] and bbox[1] < event.y < bbox[3]
#mouse click find object to move
def get_it(event):
delta=5
global cur_rec
cur_rec = PAB.find_closest(event.x, event.y) # returns the closest object
if not in_bbox(event, cur_rec): # if its not in bbox then sets current_rec as None
cur_rec = None
#mouse movement moves object
def move_it(event):
if cur_rec:
xPos, yPos = event.x, event.y
xObject, yObject = PAB.coords(cur_rec)[0],PAB.coords(cur_rec)[1]
PAB.move(PAB.gettags(cur_rec)[0], xPos-xObject, yPos-yObject)
PAB.bind('<Button-1>', get_it)
PAB.bind('<B1-Motion>', move_it)
#test rects
bob = Rect(20,20,'Bob')
rob = Rect(80,80,'Rob')
different_bob = Rect(160,160,'Bob')
PAB.pack()
root.mainloop()
這會起作用,但我不確定這是最好的方法。
基本上,它使用文本添加到矩形之后的 canvas 的事實,因此可以使用cur_rec+1
來識別它。
def move_it(event):
xPos, yPos = event.x, event.y
xObject, yObject = PAB.coords(cur_rec)[0],PAB.coords(cur_rec)[1]
# move rectangle
PAB.move(cur_rec, xPos-xObject, yPos-yObject)
# move text associated with rectangle
PAB.move(cur_rec+1, xPos-xObject, yPos-yObject)
將相同的標簽應用於文本和矩形。 然后,在調用move
時使用標簽。 這是一種方法:
class Rect:
def __init__(self, x1, y1, name):
identifier = f"id:{id(self)}"
rec = PAB.create_rectangle(x1,y1,x1+40,y1+40, fill='#c0c0c0', tags=('movable', name, identifier))
text = PAB.create_text(x1+20,y1+20, text=name, tags=('movable', identifier))
然后,您可以返回標識符而不是所選項目的索引:
def get_it(event):
delta=5
global cur_rec
for i in PAB.find_overlapping(event.x-delta, event.y-delta, event.x+delta, event.y-delta):
if hastag('movable', i):
identifier = [tag for tag in PAB.gettags(i) if tag.startswith("id:")][0]
cur_rec = identifier
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.