通过.trace()调用函数时收到“ NoneType对象不可调用”错误

时间:2019-07-04 05:16:22

标签: python-3.x tkinter

好的,所以我试图将一个非常简单的应用程序组合在一起,该应用程序实际上只是获取扫描的条形码值,该值与图像文件绑定,然后进入图像字典,找到其键与条形码匹配的图像值,并在Tkinter窗口中显示该图像。

实际上,当仅使用原始input()值时,它始终可以正常工作,但是当我尝试将“输入”框合并到窗口中以获取条形码值时,就遇到了问题。

我希望Entry窗口小部件在被编辑时就启动一个功能,因此只需扫描条形码即可显示图像。我查找了解决方案,发现的最常见的解决方案是使用StringVar,将其绑定到Entry小部件,然后在Entry小部件中的值发生更改时使用.trace()启动所需的函数。 / p>

问题是,每当我将条形码扫描到“输入”框中时,都会出现以下错误:

Exception in Tkinter callback  
Traceback (most recent call last):  
  File "c:\program files\python37\Lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)  
TypeError: 'NoneType' object is not callable  

这是我的完整代码。我尽力注释掉并尽力解释了该过程。自然,它将无法获取图像文件并使用它们来填充字典,但希望只是查看一下,您就能告诉我哪里出了问题。

from PIL import Image
from PIL import ImageTk as itk
import tkinter as tk
import cv2
import glob
import os, os.path


# INITIALIZE TKINTER WINDOW #
window = tk.Tk()
window.title('Projector Test')
#window.overrideredirect(1)


# Function to kick off whenever Tkinter Entry value is edited. Grabs value of StringVar and assigns it to variable 'barcode'. Checks to see if the barcode
# value is in 'images' dictionary. If so, grab image and display on Tkinter Canvas. If not, display Error message image.
def barcodeScanImage():
  barcode = str(sv.get())

  if barcode in images:
    image_file = images.get(barcode)
    scanImage = itk.PhotoImage(image_file)
    width, height = image_file.size
    canvas.create_image(0, 0, image = scanImage, anchor = tk.NW)

  else:
    image_file = images.get('error.gif')
    errorImage = itk.PhotoImage(image_file)
    width, height = image_file.size
    canvas.create_image(0, 0, image = errorImage, anchor = tk.NW)


# Create Dictionary 'images' to store image files in. #
images = {}


# Iterate through projectorImages folder in directory and store each image found there in the 'images' dictionary, with its Key as its filename. #
for filename in os.listdir('projectorImages\\'):
  image = Image.open(os.path.join('projectorImages\\', filename))
  images[filename] = image


# Create startImage variable. Use .size function to get its width and height, which will be plugged into the tk.Canvas width and height arguments.
# This ensures the displayed image will be displayed in its entirety.
startImage = images.get('start.gif')
width, height = startImage.size
canvas = tk.Canvas(master = window, width = width, height = height)


# Create startImageReady variable reference to the same image file, using the itk.PhotoImage function to convert it into a readable format for Tkinter.
# Then, use canvas.create_image to actually display the image in the Tkinter canvas.
startImageReady = itk.PhotoImage(images.get('start.gif'))
canvas.pack()
canvas.create_image(0, 0, image = startImageReady, anchor = tk.NW)

sv = tk.StringVar()
entry = tk.Entry(master = window, textvariable = sv)
sv.trace("w", callback = barcodeScanImage())
entry.pack()


window.mainloop()

非常感谢您的宝贵时间。我一直在试图找出导致此问题的原因,但是我对我的初学者却束手无策!哈哈

1 个答案:

答案 0 :(得分:0)

考虑以下代码行:

sv.trace("w", callback = barcodeScanImage())

在功能上与以下代码相同:

result = barcodeScanImage()
sv.trace("w", callback=result)

由于barcodeScanImage()返回None,因此与此相同:

sv.trace("w", callback=None)

调用trace时,必须给它一个对函数的引用(请注意缺少的()):

sv.trace("w", callback=barcodeScanImage)

但是,当您设置跟踪时,tkinter会将一些其他参数传递给您需要准备接受的函数。由于不使用它们,因此可以忽略它们:

def barcodeScanImage(*args):
   ...

有关传入的参数的更多信息,请参见以下问题:What are the arguments to Tkinter variable trace method callbacks?

相关问题