How can you run loops alongside tkinter? – Python QR code reader GUI

I am trying to write a Tkinter application that will also process QR codes. For that to work, I need to have a loop checking if the QR code is valid and I need to make a post request. I’m fully aware that the way I have coded this is highly inefficient. Is there a better way to do this? My Pi’s CPU is at 200%. Here is what I have so far:

import cv2
import tkinter as tk
from PIL import Image, ImageTk
import sys
import os
import pyzbar.pyzbar as zbar
import threading
import requests
import queue

result = ()
decodedCode = ""

logo     = "logo.png"
settings = "settings.png"

if os.environ.get('DISPLAY','') == '':
    print('no display found. Using :0.0')
    os.environ.__setitem__('DISPLAY', ':0.0')

#create main window
master = tk.Tk()
ttelogo = tk.PhotoImage(file = logo)
settingslogo = tk.PhotoImage(file = settings)

#settings button
settings_frame = tk.Frame(master,width=50,height=50,bg="white")
settings_frame.pack_propagate(0) # Stops child widgets of label_frame from resizing it
settingsBtn = tk.Button(settings_frame, image=settingslogo).pack(),y=0)

img = tk.Label(master, image=ttelogo, bg='white')
img.image = ttelogo,y=10)

#Name Label
label_frame = tk.Frame(master,width=400,height=100,bg="white")
label_frame.pack_propagate(0) # Stops child widgets of label_frame from resizing it
tk.Label(label_frame,bg="white",fg="black",text="John Smith Smithington III",font=("Calibri",22)).pack(),y=140)

#Instructions Label
instructions_frame = tk.Frame(master,width=440,height=100,bg="white")
instructions_frame.pack_propagate(0) # Stops child widgets of label_frame from resizing it
tk.Label(instructions_frame,bg="white",fg="black",text="Place your pass under the scanner below.",font=("Calibri",10)).pack(),y=210)

#Camera Window
cameraFrame = tk.Frame(master, width=440, height=480), y=260)

#Camera Feed
lmain = tk.Label(cameraFrame), y=0)
cap = cv2.VideoCapture(0)

def startScanning():
    global cap
    _, frame =
    frame = cv2.flip(frame, 1)
    cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
    img = Image.fromarray(cv2image)
    imgtk = ImageTk.PhotoImage(image=img)
    lmain.imgtk = imgtk
    lmain.after(10, startScanning)

def processScan():
    global decodedCode
    stopped = False
    delay = 1
        ret = cv2.waitKey(delay) & 0xFF
        if ret == ord('c'): # continue
            stopped = False
            delay = 1
        if ret == ord('q'):
        if stopped or (ret == ord('s')): # stop
            stopped = True
            delay = 30

        # Capture frame-by-frame
        ret, frame =

        decodedObjects = zbar.decode(frame)
        if len(decodedObjects) > 0:
            stopped = True
            for code in decodedObjects:
                #API Calls
                decodedCode ='utf-8')

    # When everything done, release the capture

def checkCode():
    global decodedCode
    while True:
        if decodedCode != "":
            print (decodedCode)
            result ="", data={'action': 'validate_scan', 'uuid': decodedCode}).text
            decodedCode = ""

startScanning()  #Display 2
threading.Thread(name='background', target=processScan).start()
threading.Thread(name='background2', target=checkCode).start()
master.mainloop()  #Starts GUI