Why do I get this error:
File "exampleTreeCanvas.py", line 59, in treeImageSelect
theImage = ImageTK.PhotoImage(Image.open(imageWhere)) #this line produces the error
NameError: name 'ImageTK' is not defined
when I run the following code and trigger the treeImageSelect function by clicking a .png file in the TreeView (which I'm trying to use as a file browser) of the program?
import os
import glob
import tkinter
from tkinter import *
from tkinter import ttk
from PIL import Image, ImageTk
root = Tk()
def on_vertical(event):
picCanvas.yview_scroll(-event.delta, 'units')
def on_horizontal(event):
picCanvas.xview_scroll(-event.delta, 'units')
def populate_tree(tree, node):
if tree.set(node, "type") != 'directory':
return
path = tree.set(node, "fullpath")
tree.delete(*tree.get_children(node))
parent = tree.parent(node)
special_dirs = [] if parent else glob.glob('.') + glob.glob('..')
for p in special_dirs + os.listdir(path):
ptype = None
p = os.path.join(path, p).replace('\\', '/')
if os.path.isdir(p): ptype = "directory"
elif os.path.isfile(p): ptype = "file"
fname = os.path.split(p)[1]
id = tree.insert(node, "end", text=fname, values=[p, ptype])
if ptype == 'directory':
if fname not in ('.', '..'):
tree.insert(id, 0, text="dummy")
tree.item(id, text=fname)
elif ptype == 'file':
size = os.stat(p).st_size
tree.set(id, "size", "%d bytes" % size)
def populate_roots(tree):
dir = os.path.abspath('.').replace('\\', '/')
node = tree.insert('', 'end', text=dir, values=[dir, "directory"])
populate_tree(tree, node)
def update_tree(event):
tree = event.widget
populate_tree(tree, tree.focus())
def treeImageSelect(event):
if len(tree.selection()) == 1:
filename, file_extension = os.path.splitext(tree.item(tree.selection()).get('values')[0])
if file_extension == ".png":
global imageWhere
global theImage
imageWhere = tree.item(tree.selection()).get('values')[0]
theImage = ImageTK.PhotoImage(Image.open(imageWhere)) #this line produces the error
picCanvas.itemconfigure(canvasImage, image = theImage)
picCanvas.config(scrollregion=(0,0, theImage.width(), theImage.height()))
def autoscroll(sbar, first, last):
"""Hide and show scrollbar as needed."""
first, last = float(first), float(last)
if first <= 0 and last >= 1:
sbar.grid_remove()
else:
sbar.grid()
sbar.set(first, last)
contents = ttk.Frame(root, padding=(3,3,3,3), width=200, height=200)
treecontent = ttk.Frame(contents, padding=(3,3,3,3), width=200, height=200)
picFrame = ttk.Frame(contents, padding=(3,3,3,3), width=200, height=200)
hp = Scrollbar(picFrame, orient=HORIZONTAL)
vp = Scrollbar(picFrame, orient=VERTICAL)
picCanvas = Canvas(picFrame, scrollregion=(0, 0, 1000, 1000), yscrollcommand=vp.set, xscrollcommand=hp.set)
hp['command'] = picCanvas.xview
vp['command'] = picCanvas.yview
imageWhere = 'example.png'
theImage = ImageTk.PhotoImage(Image.open(imageWhere))
canvasImage = picCanvas.create_image(0,0,image=theImage, anchor='nw')
picCanvas.config(scrollregion=(0,0,theImage.width(), theImage.height()))
contents.grid(column=0, row=0, sticky=(N,S,W,E))
hp.grid(column=0, row=1, sticky=(W,E))
vp.grid(column=1, row=0, sticky=(N,S))
picFrame.grid(column=1, row=0, sticky=(N,S,E,W))
picCanvas.grid(column=0, row=0, sticky=(N,S,E,W))
tree = ttk.Treeview(treecontent, columns=("fullpath", "type", "size"), displaycolumns="size", yscrollcommand=lambda f, l: autoscroll(vsb, f, l), xscrollcommand=lambda f, l:autoscroll(hsb, f, l))
vsb = ttk.Scrollbar(treecontent, orient="vertical")
hsb = ttk.Scrollbar(treecontent, orient="horizontal")
vsb['command'] = tree.yview
hsb['command'] = tree.xview
tree.heading("#0", text="Directory Structure", anchor='w')
tree.heading("size", text="File Size", anchor='w')
tree.column("size", stretch=0, width=100)
populate_roots(tree)
tree.bind('<<TreeviewOpen>>', update_tree)
tree.bind('<<TreeviewSelect>>', treeImageSelect)
tree.grid(column=0, row=0, sticky='nswe')
vsb.grid(column=1, row=0, sticky='ns')
hsb.grid(column=0, row=1, sticky='ew')
treecontent.grid(column=0, row=0, rowspan=4, sticky='nesw')
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
contents.columnconfigure(0, weight=1)
contents.columnconfigure(1, weight=1)
contents.rowconfigure(0, weight=1)
treecontent.rowconfigure(0, weight=1)
treecontent.columnconfigure(0, weight=1)
picFrame.columnconfigure(0, weight=1)
picFrame.rowconfigure(0, weight=1)
picCanvas.bind('<MouseWheel>', on_vertical)
picCanvas.bind('<Shift-MouseWheel>', on_horizontal)
root.mainloop()
Sorry it's so long, but I couldn't figure out how to shorten it without breaking it.
For added confusion, when I run this similar (but shorter) code, I get no errors at all:
from tkinter import *
import tkinter.ttk as ttk
from PIL import Image, ImageTk
def on_vertical(event):
canvas.yview_scroll(-event.delta, 'units')
def on_horizontal(event):
canvas.xview_scroll(-event.delta, 'units')
def getImage():
global imageWhere
theImage = ImageTk.PhotoImage(Image.open(imageWhere))
return theImage
root = Tk()
h = Scrollbar(root, orient=HORIZONTAL)
v = Scrollbar(root, orient=VERTICAL)
canvas = Canvas(root, scrollregion=(0, 0, 1000, 1000), yscrollcommand=v.set, xscrollcommand=h.set)
h['command'] = canvas.xview
v['command'] = canvas.yview
imageWhere = 'example.png'
theImage = getImage()
canvas.create_image(0,0,image=theImage, anchor='nw')
canvas.grid(column=0, row=0, sticky=(N,W,E,S))
canvas.bind_all('<MouseWheel>', on_vertical)
canvas.bind_all('<Shift-MouseWheel>', on_horizontal)
h.grid(column=0, row=1, sticky=(W,E))
v.grid(column=1, row=0, sticky=(N,S))
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0, weight=1)
root.mainloop()
What's causing the issue? Why can I use ImageTK everywhere except in the function called by the treeView?
Background: I'm using Python 3.4, Tkinter 8.5.18, Pillow (dunno the version), and Mac OS X 10.9.5. The idea here is to have the program change the Canvas's image to whatever .png file the user selects in the Treeview. I'm a complete novice at both Python and Tkinter.
You have a typo: it's ImageTk
, not ImageTK
.