Skip to content
Advertisement

How to draw lines between widgets in Tkinter?

I have written a script that takes in a file of the format

handgun: bullets magazines 
bullets: labor ore 
magazines: 
ore: 
labor: 
bombs: ore 
turret: bullets

Where each line in the list represents a ‘parent’ node and its list of ‘child’ nodes. So far I have written a script such that these nodes are printed out like a tree, and now I want to try to draw lines/arrows between these nodes. My current python script is as follows:

from ast import Delete
from dataclasses import replace
from os import link, remove
from tkinter import Canvas, Frame
import string
import tkinter as tk
import re

def fileReadIn():
    f = open("list.txt", "r")

    links = []

    for line in f:
        if re.search('.*:.*', line) != None:
            parentAndChild = re.split(':', line)
            childStr = parentAndChild[1]
            childStr = childStr.replace('n', '')
            newChilStr = childStr.split(' ')
            newChilStr.remove('')
            newChilStr.remove('')
            parentAndChild[1] = newChilStr
            links.append(parentAndChild)

    f.close()  

    return links  


#read in the masterlist from the file as a list, and links as dictionary, then and 
generate the tree
links = fileReadIn()

#open the gui window
window = tk.Tk()
window.geometry('800x800')

cur_row = []
pos_x = 300
pos_y = 0

#generate the top row
for i in links:
    isChild = False

    #make a node for the parent
    nodeparent = tk.Label(text=str(i[0]), background='black', name=str(i[0]))
    #check to see if node is a child of any other node - if not, place at top of window
    for m in links:
        for k in m[1]:
            if str(k) == str(i[0]):
                isChild = True

    if isChild == False:
        nodeparent.place(x=pos_x, y=pos_y)
        pos_x += 80
        cur_row.append(str(i[0]))

#make the rest of the rows
treeFinished = False
pos_y += 80
pos_x = 300
children = []
temp_row = []


while treeFinished == False:
    treeFinished = True

    for i in cur_row:
        for j in links:
            if i == j[0]:
                if len(j[1]) != 0:
                    treeFinished = False

    for i in cur_row:
        for j in links:
            if i == j[0]:
                children = j[1]
                for k in children: 
                    if k in temp_row:
                        continue
                    else:
                        node = tk.Label(text=k, background='black', name=k).place(x=pos_x, y=pos_y)
                        temp_row.append(k)
                        pos_x += 80

    for i in temp_row:
        for j in temp_row:
            for k in links:
                if j == k[0]:
                    for m in k[1]:
                        if i == m:
                            window.children[i].destroy()
                            temp_row.remove(i)

    cur_row = temp_row
    temp_row = []
    pos_y += 80
    pos_x = 300

window.mainloop()

I’ve tried using a canvas to do a create_line but was unsuccessful with this. Maybe I’m just missing something obvious, but does anyone have any advice on how to approach this?

Advertisement

Answer

Update: I fixed this issue! It turns out I just needed to scale the canvas to be the same size as my window.

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement