簡體   English   中英

如何在 tkinter canvas 中一起移動多個對象?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM