I am trying to display an image in tkinter treeview. I have been reading possible solutions but none seems to work, I keep getting a blank tree only with the column heading. For what I have been reading, I have to keep a reference to the PhotoImage, but regardless of how much I try it just won't happen. A simple code example can be found below:
```import tkinter as tk
from tkinter import ttk
from PIL import ImageTk as itk
import PIL.Image
import io
s= tk.Tk()
s.title('No *£/**@#* image showing')
s.geometry('400x400')
s.rowconfigure(1, weight = 1)
s.columnconfigure(1,weight=1)
headings=['Image']
p = '032f8072.gif'
img1 = PIL.Image.open('032f8072.gif')
#img1 = img1.resize((10,10))
img = itk.PhotoImage(img1)
tree = ttk.Treeview(s)
tree.grid(column=1,row=1,sticky='NSEW')
tree['columns']=headings
tree['show']='headings'
for i in headings:
tree.heading(i,text=i)
tree.column(0, width=125,stretch=True)
#tree.column(1, width=125,stretch=True)
tree.insert('','end','0', open =True, image= img)
tree.image = img
s.mainloop()```
I have tried with .gif and .png, i have tried with both PIL.Image and Imagetk.PhotoImage togeter and individually. I have also tried keeping img inside a list to be called from the list to avoid a missing reference.
I really need to get this small piece of code right and I am really frustrated with this little piece holding me back. I would really appreciate if someone could help me with this.
kind regards
CodePudding user response:
This took awhile to figure out! I eventually found this answer to a similar question from 10 months ago (not officially an answer but look in the comments under the question): Treeview Image not displaying
The user said the comment solved their problem, so I tried applying it to your example. What the commenter means is that the line tree['show'] = 'headings'
forces the Treeview to only display the headings, and not the main body of the tree. To fix this, replace that line with the following:
tree['show'] = ('headings', 'tree')
to show all of the tree, and the image should start showing up.
CodePudding user response:
You can create the columns using tree['columns'], but as ne0n p1atypus say, you can't display them using tree['show']. You can still enter the name for the columns manually with explorer_tree.heading("#0",text="Image",anchor= 'center') note that '#0' refers to the column in which the image will be displayed. I didn't try entering the column name using for loop. Also, when trying to construct a treeview to display images in different rows using a for loop, this algorithm has to be within the function that defines the treeview and all the PhotoImage objects must be append to a list to keep its reference, otherwise they'll be collected as garbage. I'll leave an example below.
global eow
global dffile
global temp_result
global explorer_tree
#Define window and treeview
explorer_headings = ["Name",'Code', 'Supplier Code']
temp_list=[]
eow= Toplevel(acm)
eow.title('Stock Explorer')
eow.geometry('400x650')
eow.geometry(" 0 0")
eow.minsize(400,650)
eow.state('zoomed')
eow.grab_set()
#style
style2 = ttk.Style()
style2.theme_use("awdark")
style2.configure("2style.Treeview.Heading",font=('Calibri', 18,'bold')) # Modify the font of the headings
style2.configure("2style.Treeview", font=('Calibri', 20),rowheight=100)
eow['bg']='black'
#Columns and rows
eow.columnconfigure(0, weight=1)
eow.columnconfigure(1, weight =2)
eow.columnconfigure(2, weight =2)
eow.columnconfigure(3, weight =1)
eow.rowconfigure(1, weight=4)
eow.rowconfigure(2, weight=2)
eow.rowconfigure(3, weight=2)
eow.rowconfigure(4, weight=2)
eow.rowconfigure(5, weight=1)
#Treeview to display data
explorer_tree = ttk.Treeview(eow, style='2style.Treeview',height=3)
explorer_tree.grid(column=1,row=2,sticky='NSEW', columnspan=2, rowspan=2)
#treeview scrollbars
xscroll_file_data= tk.Scrollbar(eow, orient='horizontal', command= explorer_tree.xview)
yscroll_file_data= tk.Scrollbar(eow, orient='vertical', command= explorer_tree.yview)
xscroll_file_data.grid(column=1,row=5,sticky='NEW',columnspan=2)
yscroll_file_data.grid(column=3,row=2,sticky='WNS',rowspan= 3)
explorer_tree.configure(yscrollcommand=yscroll_file_data.set)
add_part_button = Button(eow, text='Add Part',font=('Calibri', 14,'bold'),
activebackground='white', activeforeground='black',relief='raised', borderwidth=5
, command = add_part_from_pic_list)
add_part_button.grid(column=1, row=5, sticky='NSEW', padx=100, pady=40)
notfound_button = Button(eow, text='Part Not In List',font=('Calibri', 14,'bold'),
activebackground='white', activeforeground='black',relief='raised', borderwidth=5)
notfound_button.grid(column=2, row=5, sticky='NSEW', padx=100, pady=40)
code_label = Label(eow, text='Code: ' str(code) ' Name: ' online_name,background='black',
foreground='white',font=('Calibri', 18))
code_label.grid(column=1,row=1, sticky = 'NSEW',pady=10, padx=20)
#Name the headings
explorer_tree['columns']=explorer_headings
explorer_tree.heading("#0",text="Image",anchor= 'center')
explorer_tree.heading(0,text="Name",anchor= 'center')
explorer_tree.heading(1,text="Code",anchor= 'center')
explorer_tree.heading(2,text="Supplier Code",anchor= 'center')
#Format the columns
explorer_tree.column('#0', width=130,stretch=False)
explorer_tree.column(0,width=200, anchor='center',stretch=True)
explorer_tree.column(1,width= 200, anchor='center', stretch=False)
explorer_tree.column(2, anchor='center',stretch=False)
explorer_tree.tag_configure('even',foreground='black',background='white')
children = explorer_tree.get_children()
eow.protocol("WM_DELETE_WINDOW",Instant_exit)
explorer_tree.bind("<Double-1>", add_part_from_pic_list)
#construct tree
temp_list=[]
for i in range(len(temp_result)):
for j in range(len(dffile['Name'])):
if temp_result[i] == dffile['Name'][j]:
children1 = explorer_tree.get_children()
temp_row = [dffile['Name'][j],dffile['Code'][j],dffile['Supplier Code'][j]]
p = temp_row[1] ".png"
pp = "images/" temp_row[1] ".png"
np = 'images/noimage.png'
try:#Append the PhotoImage object to a list rather than to a variable This will avoid the image being collected as garbage
temp_list.append(ImageTk.PhotoImage(Image.open(pp).resize((100,100),Image.ANTIALIAS)))
except FileNotFoundError:
temp_list.append(ImageTk.PhotoImage(Image.open(np).resize((100,100),Image.ANTIALIAS)))
continue
if len(children1)%2 == 0: #When calling the image for tree.insert, call the image from the list i.e. temp_list[i]
explorer_tree.insert('','end',iid=(len(children1)), image=temp_list[i], values=(temp_row[0],temp_row[1],
temp_row[2]),tags=('even'))
else:
explorer_tree.insert('','end',iid=(len(children1)), image=temp_list[i], values=(temp_row[0], temp_row[1],
temp_row[2]),tags=('odd'))
eow.mainloop() ```