在python和tkinter中为Entry textchanged事件提供延迟

2024-05-23 07:58:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我的代码有问题

我用python和tkinter开发我的程序

但我有一个问题让我陷入了困境

我正在构建一个员工附件应用程序

员工有一个ID, 因此,在我的应用程序中,员工在我的表单中的textboxt上输入他/她的id

像这样 enter image description here

问题是,每个员工的len(id)在9到10之间

所以我想在len(id)输入为9之后创建一个事件触发启动

ids = StringVar(value="")
ids.trace("w", lambda name, index, mode, ids=ids: textchanged(ids))
inputid = tkinter.Entry(window,font="Helvetica 20 bold",textvariable=ids)
inputid.pack()
inputid.place(relx=0.5,rely=0.187,width=300,height=30,anchor='sw',)
inputid.size()

def textchanged(ids):
id = ids.get()
if len(id) >= 9:
    time.sleep(3)
    print(id)
    compareimage(id)

问题是,在textbox中输入8个字符id后,textbox停止获取输入 在文本框中输入长度为9的id之前,我无法输入

但在我的控制台中,它仍然可以打印不超过9个长度的id

enter image description here

我怎么解决这个问题呢,

有人能帮我吗

我将此代码添加到我的问题中

def compareimage(id):
    try:
        path = folder + id
        ClassNames = []
        mylist = os.listdir(path)
        for cls in mylist:
            curImg = cv2.imread(f'{path}/{cls}')
            image.append(curImg)
            ClassNames.append(os.path.splitext(cls)[0])
        encodeListKnown = finencode(image)
        print(encodeListKnown)
        print(ClassNames)
        print(mylist)
        time.sleep(3)
        while (True):
            ret, frames = cap.read()
            frames =cv2.flip(frames,1)
            gray = cv2.cvtColor(frames, cv2.COLOR_BGR2RGB)
            imgS = cv2.resize(frames, (0, 0), None, 0.25, 0.25)
            imgS = cv2.resize(frames, (0, 0), None, 0.25, 0.25)
            imgS = cv2.cvtColor(imgS, cv2.COLOR_BGR2RGB)
            facecurentframe = face_recognition.face_locations(imgS)
            encodecurframe = face_recognition.face_encodings(imgS, facecurentframe)
            encodelistface = []
            for faceloc in zip(encodecurframe, facecurentframe):
                encodeface = faceloc[0]
                encodelistface.append(encodeface)
            matches = face_recognition.compare_faces(encodeListKnown, encodelistface[0])
            facedistance = face_recognition.face_distance(encodeListKnown, encodelistface[0])
            print(encodelistface)
            print(facedistance)
            print(matches)
            a = str(matches)
            print(bool(matches))
            if (bool(matches) == True):
                print("True")
                now = datetime.now()
                stringnow = now.strftime('%y/%m/%d %H:%M:%S.%f')
                f = open(foldertxt, "a")
                logabsen = id + " , "+ stringnow  + "\n"
                f.write(logabsen )
                playsound(folderaudio)
                encodelistface.clear()
                encodeListKnown.clear()
                image.clear()
                ClassNames.clear()
                inputid.delete(0,END)
                break
            else:
                print("False")
                encodelistface.clear()
                encodeListKnown.clear()
                image.clear()
                ClassNames.clear()
                inputid.delete(0,END)
                break
    except :
        print("There is An Exception" , sys.exc_info()[0])

Tags: imageididsframes员工cv2faceprint
2条回答

我重构了您的脚本并删除了所有不必要的绒毛。我还删除了您的等待和您没有提供的compareimage调用。它很好用。我的猜测是,等待或对compareimage的调用正在窃取和/或阻止您的Entry的焦点。如果您将脚本的我的版本添加到wait中并调用,一次调用一个,您应该能够找出是什么阻止了Entry

注意:没有理由在place之前调用pack,我也不知道size()应该做什么ids已经是全球性的了,因此,您为将其插入lambda而跳过的所有环都是不必要的。如果某物是>= 9,那么它也只是> 8

import tkinter as tk

root = tk.Tk()
root.geometry('800x600+300+300')

ids = tk.StringVar(value="")

inputid = tk.Entry(root, font="Helvetica 20 bold", textvariable=ids)
inputid.place(relx=0.5, rely=0.187, width=300, height=30, anchor='sw')

def textchanged(*args):
    id = ids.get()
    if len(id) > 8:
        print(id)
        
ids.trace("w", textchanged)
        
root.mainloop()

每当更新inputid时,可以使用after()来安排超时任务。您需要在条形码扫描仪每次更新inputid之间选择足够长的超时时间。如果inputid在计划的超时之前再次更新,则需要取消上一个超时任务并重新计划另一个超时任务

如果超时任务被触发,您可以在超时回调中执行人脸识别,但建议使用线程来执行,因为这可能是一项耗时的任务,将阻塞tkinter主循环

以下是一个例子:

import tkinter as tk
import random
import threading
import time

def compareimage(id):
    face.config(text='Checking ...', image=tk.PhotoImage())
    face.update_idletasks()
    # simulate the face recognition task
    time.sleep(5)
    # show the result image
    face.image = tk.PhotoImage(file='result.png')
    face.config(text=id, image=face.image)
    ids.set('')

def text_completed(ids):
    print('timed out')
    id = ids.get()
    if len(id) > 8:
        print('id:', id)
        threading.Thread(target=compareimage, args=(id,), daemon=True).start()

def text_changed(ids):
    global timeout_id
    if timeout_id:
        # cancel previous scheduled task
        root.after_cancel(timeout_id)
    if len(ids.get()) > 0:
        # schedule a timeout task, adjust the delay to suit your real situation
        timeout_id = root.after(1000, text_completed, ids)

# simulate barcode reader input
def scan_id(n=10):
    if n > 0:
        inputid.insert('end', random.choice('1234567890'))
        inputid.after(50, scan_id, n-1)

timeout_id = None

root = tk.Tk()

tk.Label(root, text='Employee Attandance', font='Helvetica 32 bold').pack()

ids = tk.StringVar(value='')
ids.trace('w', lambda *args: text_changed(ids))

inputid = tk.Entry(root, font='Helvetica 20 bold', textvariable=ids, width=12)
inputid.pack()

face = tk.Label(root, text='', image=tk.PhotoImage(), compound='top', width=600, height=400)
face.pack()

tk.Button(root, text='Scan ID', command=lambda: scan_id(random.randrange(9,11))).pack()

root.mainloop()

请注意,按钮Scan ID用于模拟条形码阅读器

相关问题 更多 >

    热门问题