Home > OS >  tkinter: Is it possible to connect 2 frames with a line?
tkinter: Is it possible to connect 2 frames with a line?

Time:02-04

With tkinter i'm trying to build a simple GUI. but I ran into a problem.

I have 2 canvas, see the red and green squares, on a bigger canvas. I want to visually connect the 2 canvas with eachother with a line (blue).

I've created the 2 (red and green) canvasses and those canvasses move around.

but coding the blue line i'm getting stuck. I want to code a line between 2 frames that are moving around. the line must always be connected no matter how far apart the frames are from eachother. So I was wondering if this is even possible with tkinter or ttk?

below a small illustartion of what I've got in mind.

Small illustation

CodePudding user response:

The canvas doesn't provide a way to connect objects, but you can simulate it by simply drawing the line between the two objects. If the rectangles are filled in, you can draw a line from the center point of one to the center point of the other. You can then lower the lines in the stacking order so that the part of the line behind the rectangles won't show.

If you give the line a tag that can be computed, whenever either one of the rectangles move you can also recompute the coordinates of the line that connects them.

import tkinter as tk
import random

def connect(a,b):
    # compupte the tag, then delete any existing lines
    # between these two objects
    tag = f"connector_{a}_{b}"
    canvas.delete(tag)

    ax0, ay0, ax1, ay1 = canvas.coords(a)
    bx0, by0, bx1, by1 = canvas.coords(b)

    x0 = (ax0   ax1) / 2
    y0 = (ay0   ay1) / 2

    x1 = (bx0   bx1) / 2
    y1 = (by0   by1) / 2

    # create the line, then lower it below all other
    # objects
    line_id = canvas.create_line(x0, y0, x1, y1, fill="blue", width=4, tags=(tag,))
    canvas.tag_lower(line_id)

def move_rectangles():
    canvas.move(f1, random.randint(-50, 50), 0)
    canvas.move(f2, 0, random.randint(-50, 50))
    connect(f1, f2)

root = tk.Tk()
canvas = tk.Canvas(root, width=400, height=500, background="white")
button = tk.Button(root, text="Move rectangles", command=move_rectangles)

button.pack(side="top")
canvas.pack(side="top", fill="both", expand=True)

f1 = canvas.create_rectangle(50,50, 150, 250, outline="red", fill="white", width=4)
f2 = canvas.create_rectangle(250,100, 350, 350, outline="green", fill="white", width=4)

connect(f1, f2)


root.mainloop()

screenshot

  •  Tags:  
  • Related