I am new to python, but have java experience. Pretty different animals. I have a method that creates a json/dictionary based on walking through a directory structure and I have it where it creates a json like the one below. I am trying to get another method to populate a treeview based on it. I have seen several examples here on stackoverflow and have attempted to follow them. Below is what I have come up with, but it always errs out after going through the first directory, like it lost track of where it was. the following errors are returned:
Traceback (most recent call last):
File "temp.py", line 147, in <module>
load_treeview_from_project_dictionary(myData, tree_view)
File "temp.py", line 134, in load_treeview_from_project_dictionary
load_treeview_from_project_dictionary(c, tree_view, int(c['index']))
File "temp.py", line 136, in load_treeview_from_project_dictionary
tree_view.insert(parent_id, "end", text=c['name'], values=("", ""))
File "C:\Users\...\AppData\Local\Programs\Python\Python39\lib\tkinter\ttk.py", line 1364, in insert
res = self.tk.call(self._w, "insert", parent, index, *opts)
_tkinter.TclError: Item 1 not found
I worked several hours trying to refactor and figure this out, but have been unsuccessful. I am now reaching out to this great community to point out the error of my ways! Please help.
import json
import tkinter
from tkinter import ttk
from tkinter.ttk import Label
myData = {
"name": "MyRoot",
"type": "directory",
"index": 0,
"children": [
{
"name": "SubDir1",
"type": "directory",
"index": 1,
"children": [
{
"name": "apic.png",
"type": "file"
}
]
},
{
"name": "SubDir2",
"type": "directory",
"index": 2,
"children": [
{
"name": "somefile.txt",
"type": "file"
},
{
"name": "anotherfile.txt",
"type": "file"
}
]
},
{
"name": "SubDir3",
"type": "directory",
"index": 3,
"children": []
},
{
"name": "SubDir4",
"type": "directory",
"index": 4,
"children": [
{
"name": "asomefile.txt",
"type": "file"
},
{
"name": "bsomefile.txt",
"type": "file"
},
{
"name": "csomefile.txt",
"type": "file"
},
{
"name": "dsomefile.txt",
"type": "file"
},
{
"name": "esomefile.txt",
"type": "file"
}
]
},
{
"name": "SubDir5",
"type": "directory",
"index": 5,
"children": [
{
"name": "NesterDir1",
"type": "directory",
"index": 6,
"children": []
}
]
},
{
"name": "SubDir6",
"type": "directory",
"index": 7,
"children": []
},
{
"name": "SubDir7",
"type": "directory",
"index": 8,
"children": []
},
{
"name": "SubDir8",
"type": "directory",
"index": 9,
"children": []
},
{
"name": "SubDir9",
"type": "directory",
"index": 10,
"children": []
},
{
"name": "SubDir10",
"type": "directory",
"index": 11,
"children": []
},
{
"name": "SubDir11",
"type": "directory",
"index": 12,
"children": []
}
]
}
def load_treeview_from_project_dictionary(data, my_tree_view, parent_id=None):
print("this:" data['name'] " called function!")
if parent_id is None:
my_tree_view.insert("", "0", text=data['name'], values=("", "")) # applies to first iteration only
if data['children'] is not None:
for c in data['children']:
print("child: " c['name'])
if c['type'] == "directory":
my_tree_view.insert('', int(c['index']), text=c['name'], values=("", ""))
load_treeview_from_project_dictionary(c, my_tree_view, int(c['index']))
else:
my_tree_view.insert(parent_id, "end", text=c['name'], values=("", ""))
load_treeview_from_project_dictionary(c, my_tree_view, parent_id)
root = tkinter.Tk()
main_label = Label(root, text="Directory Tree")
tree_view = ttk.Treeview(root, height=23)
tree_view.heading("#0", text="Directory Structure")
load_treeview_from_project_dictionary(myData, tree_view)
main_label.pack()
tree_view.pack()
root.mainloop()
Thanks in Advance!
CodePudding user response:
So. After reviewing the tutorial link posted by D.L and then combing through my code and debugging over and over, I came to the conclusion that there was too much recursion going on. Watching the flow I found that the method always stopped after the first file was added to the tree. Taking the recursive call after the file insert fixed a large part of the issue. I scrutinized the insertion process and found that I could use the indices in the json for the treeview's iid's. I then decided that it would be more efficient to use the treeview.move to place the entries where I wanted them as they are being inserted. Below is what I came up with and it works great. I am posting this here for anyone else that runs into the same issue. After the code, there is a screenshot of the resulting treeview (or a link to it due to my rank- I will try to fix that later)
import json
import tkinter
from tkinter import ttk
from tkinter.ttk import Label
myData = {
"name": "MyRoot",
"type": "directory",
"index": 0,
"children": [
{
"name": "SubDir1",
"type": "directory",
"index": 1,
"children": [
{
"name": "apic.png",
"type": "file"
}
]
},
{
"name": "SubDir2",
"type": "directory",
"index": 2,
"children": [
{
"name": "somefile.txt",
"type": "file"
},
{
"name": "anotherfile.txt",
"type": "file"
}
]
},
{
"name": "SubDir3",
"type": "directory",
"index": 3,
"children": []
},
{
"name": "SubDir4",
"type": "directory",
"index": 4,
"children": [
{
"name": "asomefile.txt",
"type": "file"
},
{
"name": "bsomefile.txt",
"type": "file"
},
{
"name": "csomefile.txt",
"type": "file"
},
{
"name": "dsomefile.txt",
"type": "file"
},
{
"name": "esomefile.txt",
"type": "file"
}
]
},
{
"name": "SubDir5",
"type": "directory",
"index": 5,
"children": [
{
"name": "NestedDir1",
"type": "directory",
"index": 6,
"children": [
{
"name": "yetAnotherfile.txt",
"type": "file"
}
]
}
]
},
{
"name": "SubDir6",
"type": "directory",
"index": 7,
"children": []
},
{
"name": "SubDir7",
"type": "directory",
"index": 8,
"children": []
},
{
"name": "SubDir8",
"type": "directory",
"index": 9,
"children": []
},
{
"name": "SubDir9",
"type": "directory",
"index": 10,
"children": []
},
{
"name": "SubDir10",
"type": "directory",
"index": 11,
"children": []
},
{
"name": "SubDir11",
"type": "directory",
"index": 12,
"children": []
}
]
}
def load_treeview_from_project_dictionary(data, my_tree_view, parent_id=None):
print('this:' data['name'] ' called function!')
if parent_id is None:
my_tree_view.insert('', '0', text=data['name'], iid=0) # applies to first iteration only
for c in data['children']:
print('child: ' c['name'])
if c['type'] == 'directory':
my_tree_view.insert('', 'end', text=c['name'], iid=c['index'])
my_tree_view.move(c['index'], data['index'], 'end')
load_treeview_from_project_dictionary(c, my_tree_view, data['index'])
else:
file_index = my_tree_view.insert('', 'end', text=c['name'])
my_tree_view.move(file_index, data['index'], 'end')
root = tkinter.Tk()
main_label = Label(root, text='Directory Tree')
tree_view = ttk.Treeview(root, height=23)
tree_view.heading('#0', text='Directory Structure')
load_treeview_from_project_dictionary(myData, tree_view)
main_label.pack()
tree_view.pack()
root.mainloop()