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.
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()


