Notifications
Clear all

Barcode Scanner Fails to Rebind Kinda

4 Posts
2 Users
1 Reactions
114 Views
MadMisha
(@madmisha)
Member
Joined: 5 years ago
Posts: 343
Topic starter  

I've been writing a Python script the uses Tkinter as a GUI and it uses a barcode scanner to pull from an online database, gives me a chance to edit it, then adds it to a database.

The barcode scanner acts like a keyboard and since I'm trying to make the process as quick as possible, I want my selections to be scanned from the screen.

 

So the layout is opening screen and waiting to scan bar code(keys bound here).

Scan bar code and return info and display 4 QR codes(simply numbers 1 - 4). 1 + 3 are edit, 2 is cancel(return to start and throw away data) and 4 is accept and add to database, then wait for new bar code(isn't important right now).

If I scan 1 or 3, I can then edit the fields. To do this I call my function to unbind the keys so that I can use my keyboard.

This is where it messes up. I click the button to finish editing and call the binding function(same one that bound it in the beginning) and the scanner no longer works. If I type in a number and hit enter(mimicking exactly how the barcode scanner would enter it), it works, like it is properly bound). So, if I type in 2 and hit enter it will take me to the starting screen and the scanner works again. I have even tried clearing everything and redrawing the screen at the end of editing but it just doesn't work.

What am I missing? I have stripped down the code a bit to work here.

 

This topic was modified 4 weeks ago 3 times by MadMisha

   
Quote
MadMisha
(@madmisha)
Member
Joined: 5 years ago
Posts: 343
Topic starter  

I can't seem to post the code. It has been a long time since I've been on here, but it just comes up blank if I have the code block. I had to delete it from my original post for it to show up.


   
ReplyQuote
MadMisha
(@madmisha)
Member
Joined: 5 years ago
Posts: 343
Topic starter  

I guess it was too long.

def binder(n): #Bind and Unbind Keys here
    global allKey
    global enterKey
    if n == 0:
        allKey = barcode.bind('<Key>', barcodeGet)
        enterKey = barcode.bind('<Return>', barcodeSet)
        print('Bound Keys')#***************************************DEBUG****************************************
    elif n == 1:
        barcode.unbind('<Key>', allKey)
        barcode.unbind('<Return>', enterKey)
        print('Unbound keys')#***************************************DEBUG****************************************

The first call to this is actually on boot before it calls the first function to make the initial screen.

Here are the bound functions

def barcodeGet(n): #Captures keys from barcode.
    global fp
    fp += n.char
    #print(str(fp)) #***********************************************************DEBUG**********************************

def barcodeSet(event): #Use captured keys from barcode, triggers results
    global fp
    print(str(fp)) #***********************************************************DEBUG**********************************
    UPC_lookup(fp)
    fp=""
def finEdit(): #When edit done button is pressed, re-keybind and re-enable QR codes(I tried redrawing it here too, mimicing when it works after cancel but it didn't work)
    global editButton
    global backer
    #global mainFrame
    #global holdData
    #global tex
    #global mode
    binder(0)
    #backer.destroy()
    #mainFrame.destroy()
    #holdData.clear()
    #counter = 0
    #while counter < 13:
    #    holdData.append(tex[int(counter)].get())
    #    counter += 1
    #mode = 1
    #screenMode()
    editButton.destroy()
    backer.itemconfigure('qrs', state='normal')
    barcode.update_idletasks()

 This is what is called after things are scanned

def screenMode():
    global mode
    global mainFrame
    global currentUPC
    global dataPulled
    global holdData
    global dataCat
    global backer
    global tex
    mainFrame.destroy()
    if mode == 0:
        print('Screenmode 0')#***************************************DEBUG****************************************
        pass
    elif mode == 1: #UPC Returned, Draw fields with return
        print('Mode 1 QRMAKER, UPC Returned') #***************************************DEBUG****************************************
        backer = Canvas(master=barcode, bg='black')
        backer.pack(fill=BOTH, expand= YES)
        x = 60
        y = 700
        counter = 0
        #Insert QTY Query here
        for stuff in holdData:
            tex.append(StringVar())
            tex[int(counter)].set(str(stuff))
            hld1 = tk.Entry(master=backer, bg='black', fg='white', font='indFont', textvariable=tex[int(counter)], width=50)
            backer.create_window(y,x,window=hld1, anchor=NW)
            x = x + 50
            counter += 1
        tex.append(StringVar())
        x = 60
        y = 550
        for stuffs in dataCat:
            cld1 = tk.Label(master=backer, bg='black', fg='white', font='indFont', text=str(stuffs))
            backer.create_window(y,x,window=cld1, anchor=NW)
            x = x + 50
        qrMaker(0)
        qrMaker(1)
        mode = 2
        barcode.update_idletasks()

 Then this is the actual function that looks up Barcode in the first half or calls the functions from the QR codes

def UPC_lookup(upc):
    global mainFrame
    global backer
    global fp
    global currentUPC
    global dataPulled
    global holdData
    global dataCat
    global mode
    global tex
    global editButton
    fp=""
    if mode == 0: #fresh UPC found
        try:
            #Set Data
            holdData.clear()
            holdData.append(upc)
            print(holdData)#***************************************DEBUG****************************************
            mode = 1
            screenMode()
        except:
            print('Error!')
            fp = ''
    elif mode == 2: #Onscreen QR codes scanned
        print('Mode 2 Triggered : ' + str(upc)) #***************************************DEBUG****************************************
        if upc == '1' or upc == '3': #Edit QR code scan
            print('Mode 2-1/3')
            editButton = tk.Button(master=backer, bg='black', fg='white', font='indFont', text="Finish Editing", command=finEdit)
            backer.create_window(940,760,window=editButton, anchor=NW)
            backer.itemconfigure('qrs', state='hidden')
            binder(1)
        elif upc == '2': #Cancel scan
            print('Mode 2-2')#***************************************DEBUG****************************************
            holdData.clear()
            fp = ''
            tex.clear()
            currentUPC = ''
            backer.destroy()
            mainFrame.destroy()
            startScreen()
        elif upc == '4': #Accept scan
            print('Mode 2-4')#***************************************DEBUG****************************************
            holdData.clear()
            counter = 0
            while counter < 13:
                holdData.append(tex[int(counter)].get())
                counter += 1
            print(str(holdData))#***************************************DEBUG****************************************

 

 

 


   
ReplyQuote
byron
(@byron)
No Title
Joined: 5 years ago
Posts: 1149
 

@madmisha

I'm not sure that I can provide any assistance as the code presented is hard to follow and I think that the programming gods must have given you a pass on using globals 😀.  Its alway best to provide a minimal example that illustrates a particular issue if you can rather than the full monty, but also don't forget you can upload a file rather than a screen full of code if necessary.

Your post bought back some memories of my penultimate project in my working life when I was managing a project, part of which was to improve the workflow of a purchase invoice authorisation process that involved plonking barcodes on invoices received and scanning the invoices for automatic routing.   I was not involved in the technical details and was not involved in the programming, but I seem to remember the barcode scanner that was attached to the PC simply acted as an additional keyboard, and scanning the barcode would simply put the scanned number into the entry field, or one could type the number manually, either would work just as well.

So I take it you are doing something similar and your barcode scanner is making entries into a tk entry widget, and you are then binding the entry or return key to the entry widget that either the keyboard and possibly the scanner makes, to call a function to action something on that keypress.     

I understand you are making key bindings, and that you are then cancelling and remaking key bindings and its not working out as expected.

When using tkinter in python the use of classes, perhaps to create different Frame instances that are controlled by the root container can avoid the over use of globals and can separate the key bindings (may be 😎 ) and should prove a good way to structure your program.

But, as said, I cannot advise further on whats been presented.  I may be able to help if you provide a minimal example that illustrates the issue, otherwise I can just wish you all the best for solving your problem, and thanks for my brief trip down memory lane.

This post was modified 4 weeks ago by byron

   
DaveE reacted
ReplyQuote