Search code examples
pythontkintertreeviewpython-imaging-libraryphotoimage

Python Tkinter Treeview add an image as a column value


i'm trying to add an Image to the first column of every row on a treeview, but no matter what I do, always end up with the name of the object "pyimage1" showed instead of the actual image. As this image shows

The code that i'm using is something like this.

    from tkinter import PhotoImage.
    self._img = PhotoImage(file="resources\information_picto.gif")
    self.tree.insert('', 'end', values= self._image,self.name, self.status, self.cores, self.turn, self.added_time)

I've tried with png, with the same result, I know that my image object has been correctly created, because when debugging I can see the properties of the image, but I can't make it to show on the treeview row.

Edit:

 def __init__(self, master, **kw):
    self.SortDir = True
    f = ttk.Frame(master)
    f.pack(fill=BOTH, expand=True)
    self.dataCols = ('Project Name', 'Status', 'Cores', 'Turn', 'Added date/time')
    self.tree = ttk.Treeview(columns=self.dataCols,
                             show='headings')
    self.tree.column("Project Name", anchor="center")

    self.tree.grid(in_=f, row=0, column=0, sticky=NSEW)
    f.rowconfigure(0, weight=1)
    f.columnconfigure(0, weight=1)
    style = ttk.Style(master)
    style.configure('Treeview', rowheight=38)

    self._img = PhotoImage(file="resources\information_picto.gif")  
    self.tree.insert('', 'end', text="#0's text", image=self._img,
                     value=("A's value", "B's value"))

I'm trying with the above code, it's pretty similar to yours, but i can't find my error, however I've watch that "text" nor "image" field appear on the row, just the list of values that i passed as "value", any thoughts?


Solution

  • You can display your image using the image argument in the w.insert method. See below.

    from tkinter import PhotoImage.
    self._img = PhotoImage(file="resources\information_picto.gif")
    self.tree.insert('', 'end', text='Information_picto.gif', open=True, image=self._img, 
                     value=(self.name, self.status, self.cores, self.turn, self.added_time))
    

    Edit:

    Here is an example script showing the basic setup of a ttk.Treeview widget and how you can include an image to the #0 column and 1st row (below heading) of the widget.

    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    
    import tkinter as tk
    import tkinter.ttk as ttk
    
    class App(ttk.Frame):
    
        def __init__(self, parent=None, *args, **kwargs):
            ttk.Frame.__init__(self, parent)
            self.parent = parent
    
            # Create Treeview 
            self.tree = ttk.Treeview(self, column=('A','B'), selectmode='none', height=7)
            self.tree.grid(row=0, column=0, sticky='nsew')
    
            # Setup column heading
            self.tree.heading('#0', text=' Pic directory', anchor='center')
            self.tree.heading('#1', text=' A', anchor='center')
            self.tree.heading('#2', text=' B', anchor='center')
            # #0, #01, #02 denotes the 0, 1st, 2nd columns
    
            # Setup column
            self.tree.column('A', anchor='center', width=100)
            self.tree.column('B', anchor='center', width=100)
    
            # Insert image to #0 
            self._img = tk.PhotoImage(file="imagename.gif") #change to your file path
            self.tree.insert('', 'end', text="#0's text", image=self._img,
                             value=("A's value", "B's value"))
    
    
    if __name__ == '__main__':
        root = tk.Tk()
        root.geometry('450x180+300+300')
    
        app = App(root)
        app.grid(row=0, column=0, sticky='nsew')
    
        root.rowconfigure(0, weight=1)
        root.columnconfigure(0, weight=1)
    
        root.mainloop()
    

    Picture added.

    Respond to your Edit: See comments in the script for explanation. Also suggest you experiment the earlier script I had provided you to help you better understand how to use Treeview widget. Have fun.

    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    
    
    # tkinter modules
    import tkinter as tk
    import tkinter.ttk as ttk
    
    class App(ttk.Frame):
    
         def __init__(self, master, **kw):
            self.SortDir = True
            #f = ttk.Frame(master) #1. this widget is self, no need to assign to f. 2. You missed out .__init__().
            ttk.Frame.__init__(self, master)
            #f.pack(fill=tk.BOTH, expand=True)# redundant. done by app.grid
    
    
            #self.dataCols = ('Project Name', 'Status', 'Cores', 'Turn', 'Added date/time')
            #I have removed 'Project Name' since it is #0. self.dataCols is for #01, #02, .. onwards
            self.dataCols = ('Status', 'Cores', 'Turn', 'Added date/time')
            #self.tree = ttk.Treeview(self, columns=self.dataCols, show='headings')
            # Did not define widget's parent? I have added. Picture not shown because u used option show='headings'
            self.tree = ttk.Treeview(self, columns=self.dataCols)
            #self.tree.column("Project Name", anchor="center")        
            #self.tree.grid(in_=f, row=0, column=0, sticky=tk.NSEW)
            # I have removed "in_=f" since parent has been defined.
            self.tree.grid(row=0, column=0, sticky=tk.NSEW)
    
            # Setup column heading
            self.tree.heading('#0', text='Project Name', anchor='center')
            self.tree.heading('#1', text='Status', anchor='center')
            self.tree.heading('#2', text='Cores', anchor='center')
            self.tree.heading('#3', text='Turn', anchor='center')
            self.tree.heading('#4', text='Added date/time', anchor='center')
    
    
            #f.rowconfigure(0, weight=1) # Use with .grid but not for .pack positioning method
            #f.columnconfigure(0, weight=1) # same as above
            style = ttk.Style(master)
            style.configure('Treeview', rowheight=38)
    
            self._img = tk.PhotoImage(file="test50.gif")  
            self.tree.insert('', 'end', text="#0's text", image=self._img,
                             value=("A's value", "B's value"))
    
    if __name__ == '__main__':
        root = tk.Tk()
        root.geometry('450x180+300+300')
    
        app = App(root)
        app.grid(row=0, column=0, sticky='nsew')
    
        root.rowconfigure(0, weight=1)
        root.columnconfigure(0, weight=1)
    
        root.mainloop()