簡體   English   中英

Python canvas 用鼠標移動物品 tkinter

[英]Python canvas move items with mouse tkinter

我寫了一個簡單的 python 代碼,它創建了 canvas 和 canvas 中的項目只能使用鼠標自由移動。 此外,可以移動在 canvas 中創建的先前形狀。 但是,我在這里有一些問題:

  1. 移動 1 rect 之類的項目時。 1 個圓圈,不知何故它們重疊或其中一個在 canvas 中完全看不見。
  2. 我的刪除按鈕有效,但使用刪除按鈕后我無能為力。 系統報錯。 (我認為我無法將 object_id 值設為 0,因為重置后,我添加了 rect。而 object_id 不是從 0 開始的,有趣的是它沒有坐標??)
  3. 當我嘗試在 canvas 中拖動形狀時,鼠標會自動選擇形狀的左上角,我該如何更改? (也許從我嘗試用鼠標單擊的點移動形狀)

我的代碼:

from tkinter import *

from tkinter import messagebox

def click(event):
    my_label.config(text="Coordinates: x: "+ str(event.x) +" y: " +str(event.y)) 
    
    if object_id is not None: 
        for i in range(object_id):
            coord = my_canvas.coords(i+1) # +1 added because for loop starts from 0
            print(coord)
            print(object_id)
            if ((event.x<=coord[2]+10) and (event.x>=coord[0]-10) and (event.y<=coord[3]+10) and 
            (event.y>=coord[1])-10):

                print(coord)
                width = coord[2] - coord[0]
                height = coord[3] - coord[1]
                my_canvas.coords(i+1, event.x, event.y, event.x+width, event.y+height)
            else:
                pass
    else:
        pass
        
def label_mod(event): #While not pressing button, show coords!
    my_label.config(text="Coordinates: x: "+ str(event.x) +" y: " +str(event.y))

def delete():
    global object_id #Delete butonunda sistem fail oluyor
    msg = messagebox.askyesnocancel('Info', 'Delete my_canvas ?')
    if msg == True:
        my_canvas.delete(ALL)
        print(object_id)
        object_id=0 
        print(object_id)

def create_rectangle():
    global object_id
    object_id=my_canvas.create_rectangle(10, 10, 70, 70, fill='white', outline='blue', width=3)

def create_line():
    global object_id
    object_id=my_canvas.create_line(200, 200, 100, 100, fill='red', width=5)
    
def create_circle():
    global object_id
    object_id=my_canvas.create_oval(10, 10, 70, 70, fill='orange', outline='blue')
    
# Main Codes

object_id = 0

root = Tk()
root.title('Moving objects')
root.resizable(width=False, height=False)
root.geometry('1200x600+100+50')
root.configure(bg='light green')

my_label=Label(root, text="")
my_label.pack()

my_canvas = Canvas(root, bg='white', height=500, width=500)
my_canvas.pack(side=RIGHT)
my_canvas.bind("<B1-Motion>", click)
my_canvas.bind("<Motion>", label_mod)

btn_line = Button(root, text='Line', width=30, command=create_line)
btn_line.pack()

btn_rectangle = Button(root, text='Rectangle', width=30, command=create_rectangle)
btn_rectangle.pack()

btn_circle = Button(root, text='Circle', width=30, command=create_circle)
btn_circle.pack()

btn_delete = Button(root, text='Delete', width=30, command=delete)
btn_delete.pack()

root.mainloop()

你根本不需要object_id 您可以使用my_canvas.find_overlapping()到 select 您想要的 canvas 項目,並使用my_canvas.move()移動所選項目:

def on_click(event):
    selected = my_canvas.find_overlapping(event.x-10, event.y-10, event.x+10, event.y+10)
    if selected:
        my_canvas.selected = selected[-1]  # select the top-most item
        my_canvas.startxy = (event.x, event.y)
        print(my_canvas.selected, my_canvas.startxy)
    else:
        my_canvas.selected = None

def on_drag(event):
    if my_canvas.selected:
        # calculate distance moved from last position
        dx, dy = event.x-my_canvas.startxy[0], event.y-my_canvas.startxy[1]
        # move the selected item
        my_canvas.move(my_canvas.selected, dx, dy)
        # update last position
        my_canvas.startxy = (event.x, event.y)

def delete():
    msg = messagebox.askyesnocancel('Info', 'Delete my_canvas ?')
    if msg == True:
        my_canvas.delete(ALL)

def create_rectangle():
    my_canvas.create_rectangle(10, 10, 70, 70, fill='white', outline='blue', width=3)

def create_line():
    my_canvas.create_line(200, 200, 100, 100, fill='red', width=5)
    
def create_circle():
    my_canvas.create_oval(10, 10, 70, 70, fill='orange', outline='blue')

...

my_canvas.bind("<Button-1>", on_click)
my_canvas.bind("<B1-Motion>", on_drag)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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