Reputation: 55
I have a GUI where results from a dataframe are populated into a treeview within python based on filters previously input. The user can then click on treeview and update the values to the desired number. The number of rows within the view can vary from 1 - 20+. Once the user has updated the view as desired, I have a button below "Check Allocation".
It is at this point I want to "export" the treeview into a dataframe for me to run against another table. I cant seem to simply export this as a dataframe. Is there any work around this? I only need the first and last columns (of the 8) to check the newly updated file.
Here is what I have so far.
def PrintAllocation(self):
treeview = tkk.Treeview(root)
treeview.grid(column = 1, row = 8, columnspan = 4, padx = 1, pady = 1)
cols = list(matches.columns)
treeview["columns"] = cols
for i in cols:
treeview.column(i, width = 100, anchor = "w")
treeview.heading(i,text=i,anchor='w',)
for index, row in matches.iterrows():
treeview.insert("",0,text=index,values=list(row))
def set_cell_value(event): # Double click to enter the edit state
for item in treeview.selection():
#item = I001
item_text = treeview.item(item, "values")
#print(item_text[0:2]) # Output the value of the selected row
column= treeview.identify_column(event.x)# column
print(column)
row = treeview.identify_row(event.y) #row
cn = int(str(column).replace('#',''))
rn = int(str(row).replace('I',''))
if column == '#8':
entryedit = Text(root,width=50,height = 1)
entryedit.grid(column = 2, row = 9, padx = 1, pady = 1)
else:
entryedit = Text(root,width=10,height = 1)
entryedit.grid(column = 2, row = 9, padx = 1, pady = 1)
def saveedit():
treeview.set(item, column=column, value=entryedit.get(0.0, "end"))
entryedit.destroy()
okb.destroy()
okb = ttk.Button(root, text='OK', width=4, command=saveedit)
okb.grid(column = 3, row = 9,padx = 1, pady=1)
def CheckAllocation():
children = treeview.getchildren()
for child in children:
print(treeview.set(child))
treeview.bind('<Double-1>', set_cell_value) # Double-click the left button to enter the edit
button_check = Button(root,text="Check Allocation", command = CheckAllocation)
button_check.grid(column = 2, row = 10, padx = 10, pady=10)
'''
Upvotes: 0
Views: 3872
Reputation: 39
You can also do this:
row_list = []
columns = ('name', 'school', 'c3', 'c4')
for row in treeview.get_children():
row_list.append(treeview.item(row)["values"])
treeview_df = pd.DataFrame(row_list, columns = columns)
Upvotes: 1
Reputation: 4220
The current answer is good, I just wanted to add my two cents here:
self.treeview_columns = [] # list of names here
# initialize empty df
# if too big you can preallocate but probably not needed
treeview_df = pd.DataFrame(None, columns=self.treeview_columns)
for row in self.treeview.get_children():
# each row will come as a list under name "values"
values = pd.DataFrame([self.treeview.item(row)["values"]],
columns=self.treeview_columns)
# print(values)
treeview_df = treeview_df.append(values)
This way you grow your df row by row using append and you reduce the number of subsets that you need to do.
Upvotes: 0
Reputation: 311
I don't really understand your code but when I need to get a treeview to pandas I do it as follows:
First I create an empty list for each column in the treeview.
column_a_list = []
column_b_list = []
column_c_list = []
column_d_list = []
Then running through the lines of the treeview in a "for" function, I append to each column list the value of the column in each line.
for child in self.treeview.get_children():
column_a_list.append(self.treeview.item(child)["values"][0])
column_b_list.append(self.treeview.item(child)["values"][1])
column_c_list.append(self.treeview.item(child)["values"][2])
column_d_list.append(self.treeview.item(child)["values"][3])
Then I create a dictionary from all the lists, using the header as the key and lists are the values as a list.
full_treeview_data_dict = {'HEADER A': column_a_list, 'HEADER B': column_b_list, 'HEADER C': column_c_list, 'HEADER D': column_d_list,}
Then I create a dataframe from the dictionary.
treeview_df = pd.DataFrame.from_dict(full_treeview_data_dict)
Here is the full sample code in one chunk:
column_a_list = []
column_b_list = []
column_c_list = []
column_d_list = []
for child in self.treeview.get_children():
column_a_list.append(self.treeview.item(child)["values"][0])
column_b_list.append(self.treeview.item(child)["values"][1])
column_c_list.append(self.treeview.item(child)["values"][2])
column_d_list.append(self.treeview.item(child)["values"][3])
full_treeview_data_dict = {'HEADER A': column_a_list, 'HEADER B': column_b_list, 'HEADER C': column_c_list, 'HEADER D': column_d_list,}
treeview_df = pd.DataFrame.from_dict(full_treeview_data_dict)
I hope it helps.
Upvotes: 1