好的,所以我试图将一个非常简单的应用程序组合在一起,该应用程序实际上只是获取扫描的条形码值,该值与图像文件绑定,然后进入图像字典,找到其键与条形码匹配的图像值,并在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()
非常感谢您的宝贵时间。我一直在试图找出导致此问题的原因,但是我对我的初学者却束手无策!哈哈
答案 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?