от
Итак, я пытаюсь собрать действительно простое приложение, которое, по сути, просто берет отсканированное значение штрих-кода, которое привязано к файлу изображения и попадает в словарь изображений, находит изображение, ключ которого соответствует значению штрих-кода, и отображает это изображение в окне Tkinter. Я на самом деле работал последовательно, когда просто использовал необработанное значение input (), но когда я попытался встроить поле ввода в окно, чтобы получить значение штрих-кода, именно тогда я столкнулся с проблемами. Я хочу, чтобы виджет «Ввод» запускал функцию всякий раз, когда она редактировалась, так что все, что нужно сделать, это отсканировать штрих-код и появится изображение. Я искал решения для этого, и самым распространенным, что я нашел, было использование 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 голосов
от
Рассмотрим эту строку кода:
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?     
...