在 tkinter UI 中的两个对象之间绘制线条 [英] Drawing lines between two object in tkinter UI

查看:34
本文介绍了在 tkinter UI 中的两个对象之间绘制线条的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

感谢 拖放方面的大量帮助Tkinter UI 中的对象,我可以设法绘制三个可拖动的正方形.

Thanks to lots of help in Drag and drop the object in Tkinter UI, I could manage to draw three square that are draggable.

现在我试图在每个方块之间画 3 条线,但我找不到启用它的方法.我尝试的是以下内容:

Now I am trying to draw 3 lines between each squares and I cannot find way to enable it. What I tried is following :

from tkinter import *
window = Tk()
window.state('zoomed')
window.configure(bg = 'white')

def drag(event):
    new_x = event.x_root - window.winfo_rootx()
    new_y = event.y_root - window.winfo_rooty()
    event.widget.place(x=new_x, y=new_y,anchor=CENTER)

card = Canvas(window, width=10, height=10, bg='red1')
card.place(x=300, y=600,anchor=CENTER)
card.bind("<B1-Motion>", drag)

another_card = Canvas(window, width=10, height=10, bg='red2')
another_card.place(x=600, y=600,anchor=CENTER)
another_card.bind("<B1-Motion>", drag)

third_card = Canvas(window, width=10, height=10, bg='red3')
third_card.place(x=600, y=600,anchor=CENTER)
third_card.bind("<B1-Motion>", drag)

def line(x1, y1, x2, y2):
    print(x1, y1, x2, y2)
    Canvas.create_line(x1, y1, x2, y2, fill="green")

coor_1 = canvas.coords(card)
coor_2 = canvas.coords(another_card)
line(coor_1[0],coor_1[1],coor_1[0],coor_2[1])
window.mainloop()

它没有用,我不认为它会起作用,因为这段代码没有捕捉到拖动对象发生的变化,但我无法猜测如何编码,因为我不明白事件函数是如何完全工作的.我应该如何为它制作代码?

It didn't work and I don't think it will work since this code does not catch the change occurred by dragging object, But I cannot guess how to code since I do not understand how the event function works completely. How should I make a code for it ?

推荐答案

自学目的:

import tkinter as tk

window = tk.Tk()
window.state('zoomed')

class DragAndDropArea(tk.Canvas):
    def __init__(self,master, **kwargs):
        tk.Canvas.__init__(self,master, **kwargs)
        self.active = None

        card_I = self.draw_card(300,600, 100,100, 'red1')
        card_II = self.draw_card(600,600, 100,100, 'red2')
        card_III = self.draw_card(400,400, 100,100, 'red3')

        self.bind_tention(card_I,card_III)
        self.bind_tention(card_I,card_II)
        self.bind_tention(card_III,card_II)

        self.bind('<ButtonPress-1>', self.get_item)
        self.bind('<B1-Motion>',self.move_active)
        self.bind('<ButtonRelease-1>', self.set_none)
    def set_none(self,event):
        self.active = None
    def get_item(self,event):
        try:
            item =  self.find_withtag('current')
            self.active = item[0]
        except IndexError:
            print('no item was clicked')
    def move_active(self,event):
        if self.active != None:
            coords = self.coords(self.active)
            width = coords[2] - coords[0] #x2-x1
            height= coords[1] - coords[3] #y1-y2
            position = coords[0],coords[1]#x1,y1

            x1 = event.x - width/2
            y1 = event.y - height/2
            x2 = event.x + width/2
            y2 = event.y + height/2
            
            self.coords(self.active, x1,y1, x2,y2)
            try:
                self.update_tention(self.active)
            except IndexError:
                print('no tentions found')

    def update_tention(self, tag):
        tentions = self.find_withtag(f'card {tag}')
        for tention in tentions:
            bounded_cards = self.gettags(tention)
            card = bounded_cards[0].split()[-1]
            card2= bounded_cards[1].split()[-1]
            x1,y1 = self.get_mid_point(card)
            x2,y2 = self.get_mid_point(card2)
            self.coords(tention, x1,y1, x2,y2)
            self.lower(tention)

    def draw_card(self, x,y, width,height, color):
        x1,y1 = x,y
        x2,y2 = x+width,y+height
        reference = self.create_rectangle(x1,y1,x2,y2,
                                          fill = color)
        return reference
    def bind_tention(self, card, another_card):
        x1,y1 = self.get_mid_point(card)
        x2,y2 = self.get_mid_point(another_card)
        tag_I = f'card {card}'
        tag_II= f'card {another_card}'
        
        reference = self.create_line(x1,y1,x2,y2, fill='green',
                                     tags=(tag_I,tag_II))
        self.lower(reference)

    def get_mid_point(self, card):
        coords = self.coords(card)
        width = coords[2] - coords[0] #x2-x1
        height= coords[1] - coords[3] #y1-y2
        position = coords[0],coords[1]#x1,y1

        mid_x = position[0] + width/2
        mid_y = position[1] - height/2

        return mid_x,mid_y
        
area = DragAndDropArea(window, bg='white')
area.pack(fill='both',expand=1)
window.mainloop()

这篇关于在 tkinter UI 中的两个对象之间绘制线条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆