1

The script aims to read a QR code so the user does not have to press the Enter key, nor to push any button. I am reading the qr-code character by character; it contains a "." to indicate the end of the string, like: "012-ABCDE." The script works just fine even when used continuously and the dot is still in the entry. Can anybody help me to eliminate that dot, please?

import tkinter as tk
import string

class mainWindow(tk.Frame):

    def __init__(self, controller):
        askForQRCode(self, controller)

    def processQRCode(self, qrCode):        
        print('processing QR code {}'.format(qrCode))


class askForQRCode(tk.Frame):

    def __init__(self, parent, controller):
        self.parent      = parent
        self.givenString = ''

        #PANEL QR CODE
        panelQRCode = tk.PanedWindow(controller)
        panelQRCode.pack(fill='both', padx=7)
        # ... 

        #SUBJECT
        fSubject = tk.LabelFrame(panelQRCode, text='Subject ID')
        panelQRCode.add(fSubject, stretch='always')
        label = tk.Label(fSubject, text='QR Code')
        label.grid(column=0, columnspan=2, row=1)
        self.qrCodeEntry = tk.Entry(fSubject)
        self.qrCodeEntry.grid(column=0, columnspan=2, row=3, padx=7)
        self.qrCodeEntry.focus_force()
        self.qrCodeEntry.bind('<Key>', self.onQREntry)

    def onQREntry(self, event):
        theChar = event.char.upper()
        list1   = list(string.ascii_uppercase)
        list2   = ['-','0','1','2','3','4','5','6','7','8','9']
        if theChar in list1 or theChar in list2:
            self.givenString = self.givenString + theChar

        elif theChar == '.':
            self.qrCodeEntry.delete(0, tk.END)
            self.parent.processQRCode(self.givenString)


if __name__ == '__main__':
    root = tk.Tk()
    root.title('dummy')
    theMainWindow = mainWindow(root)
    root.mainloop()
Consuelo
  • 13
  • 3

1 Answers1

1

The problem is that your <Key> binding happens before the default action of the widget (ie: before the character is actually inserted into the widget).

A simple solution is to bind to <KeyRelease>, which gives the default action (bound to <KeyPress>) a chance to be fully processed before your custom code.

For a more thorough explanation of how events are processed, see this answer: Basic query regarding bindtags in tkinter

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685