title: Emulate keyboard pressing from one infinite loop to another in a GUI
body: <p>I’m trying to do a GUI where the user is gonna control the buttons by eyeblinking. Basically, a short blink should emulate pressing the keyboard key Tab (to move from one button to another) and a long blink should emulate pressing the key Space (to enter in the selected button). </p>
  
  <p>The idea is that both processes, the window and the eyeblink detection system, run at the same time. So here I get all the problems: as they are both while loops I cannot run them at the same time. </p>
  
  <p>In the code I attach, I simplify this by opening first the main window and afterwards clicking the button Start to run the eyeblink system. With pyautogui.press() I suppose to emulate the keyboard pressing in the main window. However, when the eyeblink detection system is working, the main window is no longer accessible (you cannot press anything). </p>
  
  <p>I have tried to evoke the blink function every frame instead of an endless loop, but it’s too slow and not able to properly detect the blinks. I’ve also tried multiprocessing and ‘Python quits unexpectadly’, no error shown so not sure what’s going on (the code I used to try this is at the end commented). I also tried threading but in a simple way an no error but nothing appears either (again, the code I used to try this is at the end commented). 
  Here I attach the link to the files (.mp3, .xml, .py):
  <a href="https://drive.google.com/drive/folders/1U2uwHXzl2MtSTlAKw1L68L3xcRmelP2d?usp=sharing" rel="nofollow noreferrer">https://drive.google.com/drive/folders/1U2uwHXzl2MtSTlAKw1L68L3xcRmelP2d?usp=sharing</a></p>
  
  <p>I’ve just started using Python so my knowledge is not high, I’m running out of time and I’m stuck at this point… So any help would be welcome!! Thanks in advance ;)</p>
  
  <p>MacOs
  Python 2.7
  OpenCV 3.4
  Tkinter (I just chose it because it is easy to handle yet I’m open to change if it’s neccessary)</p>
  
  <pre><code># Ventana+Blink
  from Tkinter import *
  import numpy as np
  import cv2
  # To emulate a keyboard pressing
  import pyautogui
  import time
  # To play the sounds
  import subprocess 
  # from Blink import funcion_blink
  # from multiprocessing import Process
  # import threading 
  
  
  def Onbutton_clicked():
      # while True:
      # Repeating 2 times the sound
      for x in range (0,2):
          subprocess.call(['afplay', 'alarm2.mp3'])
  
  def Onbutton2_clicked():
      # Repeating 1 times the sound
      for x in range (0,1):
          subprocess.call(['afplay', 'sound.mp3'])
  
  
  def execute_func1():
      print('enter\n')
      pyautogui.press('space')  # press the Space key
      for x in range (1,2):
          subprocess.call(['afplay', 'unconvinced.mp3'])
  
  def execute_func2():
      print('tab\n')
      pyautogui.press('tab')  # press the Tab key
      for x in range (1,2):
          subprocess.call(['afplay', 'case-closed.mp3'])
  
  def execute_func3():
      print('space\n')
      pyautogui.press('space')  # press the Space key
      for x in range (1,2):
          subprocess.call(['afplay', 'cheerful.mp3'])
  
  
  # ----- Eyeblink detection system -----
  def funcion_blink():
  #XML classifiers should be in the folder with this file
      face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
      eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')
  
      video_capture = cv2.VideoCapture(0)
      det = 0
      n = 0
  
      while True:
      # Capture frame-by-frame
          ret, frame = video_capture.read()
          gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
  
          faces = face_cascade.detectMultiScale(
              gray,
              scaleFactor=1.1,
              minNeighbors=5,
              minSize=(100, 100),
              flags=cv2.CASCADE_SCALE_IMAGE
          )
  
              # Draw a rectangle around the faces
          for (x, y, w, h) in faces:
              cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
              roi_gray = gray[y:y + h, x:x + w]
              roi_color = frame[y:y + h, x:x + w]
              eyes = eye_cascade.detectMultiScale(
                  roi_gray,
                  scaleFactor = 1.1,
                  minNeighbors = 5,
                  minSize = (30, 30),
                  flags = cv2.CASCADE_SCALE_IMAGE
              )
              for (ex, ey, ew, eh) in eyes:
                  cv2.rectangle(roi_color, (ex, ey), (ex + ew, ey + eh), (0, 255, 0), 2)
              face_img = gray[x:x + w, y:y + h]
              face_res = cv2.resize(face_img, (100, 100), interpolation=cv2.INTER_CUBIC)
              eye_reg = face_res[15:85, 20:50]
              cv2.rectangle(frame, (x+15*w/100, y + 2*h / 10), (x + w*85/100, y + (5 * h / 10)), (0, 0, 255), 2)
              if (det &lt; 10):
                  tmpl_eyes = eye_reg
                  det = det + 1
                  print('template acquired\n')
              elif (det == 10):
                          # template matching
                  wt, ht = tmpl_eyes.shape[::-1]
                          #res_templ = cv2.matchTemplate(eye_reg, tmpl_eyes, cv2.TM_CCORR_NORMED)
                  res_templ = cv2.matchTemplate(eye_reg, tmpl_eyes, cv2.TM_CCOEFF_NORMED)
                  min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res_templ)
                              # print(max_val, n)
                          #value 0.92 should be adapted to the conditions and camera position
                  if (max_val&gt;0.90):
                      n=n+1
                  else:
                      if (n&gt;=12):
                          execute_func1()
                                  #here should go the code that triggers some action when the person blinks??                 
                      elif (n&gt;=6):
                          execute_func2()              
                      elif (n&gt;=3):
                          execute_func3()
  
                      n = 0
                  print(max_val, n)
  
          # Display the resulting frame
          cv2.imshow('Video', frame)
  
          if cv2.waitKey(1) &amp; 0xFF == ord('q'):
              break
  
      # When everything is done, release the capture
      cv2.destroyAllWindows()
      video_capture.release()
  
  
  # ---- Main window ----
  def main_window():
      root= Tk()   
      root.geometry('700x700')
  
      # Create the buttons of the main window
      button=Button(root, text='alarm', command=Onbutton_clicked)
      button.bind('&lt;Return&gt;', Onbutton_clicked)
      button.pack()
  
      button2=Button(root, text='extra', command=Onbutton2_clicked)
      button2.bind('&lt;Return&gt;', Onbutton2_clicked)
      button2.pack()
  
      # By pressing this button we start running the eyeblink detection system
      button3=Button(root, text='Start', command=funcion_blink)
      button3.bind('&lt;Button-1&gt;', funcion_blink)
      button3.pack()
  
      # To maintain the window until you close it
      root.mainloop()
  
  # Execute the main window
  main_window()
  
  
  # ---- Trials ----
  
  # while True:
  #     main_window()
  #     funcion_blink()  
  # It just plays one function and when it finishes it plays the next one
  
  # Multiprocessing
  # if __name__ == '__main__':
  #     Process(target=main_window).start()
  #     Process(target=funcion_blink).start()
  # PYTHON QUITS UNEXPECTADLY
  
  # Threading
  # p1 = threading.Thread(target=main_window, args=())
  # p2 = threading.Thread(target=funcion_blink, args=())
  # p1.start()
  # p2.start()
  </code></pre>