Ошибка «NoneType Object is Callable» при вызове функции через .trace () - PullRequest
0 голосов
/ 04 июля 2019

Хорошо, я пытаюсь собрать действительно простое приложение, которое, по сути, просто берет отсканированное значение штрих-кода, которое привязано к файлу изображения и попадает в словарь изображений, находит изображение, ключ которого совпадает со штрих-кодом.значение, и отображает это изображение в окне Tkinter.

На самом деле оно работало согласованно, просто используя необработанное значение input (), но когда я попытался вставить поле ввода в окно, чтобы получить значение штрих-кодаВот тогда я столкнулся с проблемами.

Я хочу, чтобы виджет Entry запускал функцию при каждом редактировании, чтобы все, что нужно было сделать, это отсканировать штрих-код, и изображение появилось.Я искал решения для этого, и самым распространенным, что я нашел, было использование StringVar, привязка его к виджету Entry, а затем использование .trace () для запуска нужной функции всякий раз, когда значение в виджете Entry изменяется.

Загвоздка в том, что всякий раз, когда я сканирую штрих-код в поле ввода, я получаю следующую ошибку:

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 голосов
/ 04 июля 2019

Рассмотрим следующую строку кода:

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):
   ...

Для получения дополнительной информации об аргументах, которые передаются, см. Этот вопрос: Каковы аргументы метода трассировки переменных Tkinterобратные вызовы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...