Tkinter Python:在函数中调用时找不到模块?

Tkinter Python: Modules not found when called in functions?

为什么会出现此错误:

File "exampleTreeCanvas.py", line 59, in treeImageSelect
    theImage = ImageTK.PhotoImage(Image.open(imageWhere)) #this line produces the error
NameError: name 'ImageTK' is not defined

当我运行以下代码并通过单击程序的 TreeView(我试图将其用作文件浏览器)中的 .png 文件触发 treeImageSelect 函数时?

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()

抱歉太长了,但我不知道如何在不破坏它的情况下缩短它。

更令人困惑的是,当我 运行 这个类似(但更短)的代码时,我完全没有收到任何错误:

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()

是什么导致了这个问题?为什么除了treeView调用的函数外,其他地方都可以使用ImageTK?

背景:我正在使用 Python 3.4、Tkinter 8.5.18、Pillow(不知道版本)和 Mac OS X 10.9.5。这里的想法是让程序将 Canvas 的图像更改为用户在树视图中选择的任何 .png 文件。我在 Python 和 Tkinter 方面都是新手。

您打错了:是 ImageTk,而不是 ImageTK