I am trying to use an asynchronous function in python-3, but this is giving error

0

Error:

Warning (from warnings module):
  File "C:\Users\tiago.pereira\Desktop\python\kivy\kivy_teste.py", line 43
    pythoncom.PumpMessages()
RuntimeWarning: coroutine 'Keyboard' was never awaited
TypeError: an integer is required (got type coroutine)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\tiago.pereira\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pyHook\HookManager.py", line 348, in KeyboardSwitch
    event = KeyboardEvent(msg, vk_code, scan_code, ascii, flags, time, hwnd, win_name)
SystemError: <class 'pyHook.HookManager.KeyboardEvent'> returned a result with an error set


Code:

import pythoncom,pyHook
import threading
import ctypes,sys,asyncio
import cv2
import tkinter as tk
from tkinter import *


#kivy.require('1.9.0')



#def popup():
 #   popup = Popup(content=Label(text="I am popup"))s
  #  popup.open()

first = True

async def Keyboard(event):    
    print(event.GetKey())


    if event.GetKey() == 'Lcontrol':
        ctypes.windll.user32.LockWorkStation()
    elif event.GetKey() == 'Next': 
        sys.exit(0)
    else:
        await picture
        return False

async def picture():
    cap = cv2.VideoCapture(0)    
    ret,frame = cap.read()  # return a single frame in variable 'frame'
    cv2.imwrite('C:/Users/tiago.pereira/desktop/c1.png',frame)    
    cap.release()    


hm = pyHook.HookManager()
hm.KeyDown = Keyboard
#hm.MouseAll = Mouse
hm.HookKeyboard()
#hm.HookMouse()
pythoncom.PumpMessages()
    
asked by anonymous 19.11.2018 / 11:46

2 answers

2

In particular, the question you mentioned in the comments is 2010 - Python async as it is today did not even exist (neither the syntax nor the concept). Certainly this module does not support asynchronous functions.

The obvious solution here is to simply make your keyboard function a normal function, without being asynchronous. The only asynchronous thing that it does is actually in the other function - picture

which, incidentally, is wrongly called - should be await picture() . And, IF the PythonHook framework works with Python's AsyncIO, the Keyboard function itself would be suspended until picture is ready. It hardly seems to be what you really want.

What you'd like there is - whether Keyboard can be asynchronous or not - is to process the key pressed as fast as possible, if any of the keys have a long process, then you fire it as a separate asynchronous task - and it closes the Keyboard function, getting "ready to next key". That is: the Keyboard function does not have to be asynchronous - it needs to create tasks based on the keystrokes.

The way to create a new asynchronous task is with the create_task method of the event loop. (it is new in Python 3.7 In 3.5 and 3.6 it did not exist and should use ensure_future )

Even in an asynchronous function, if you do not need the return value of another asynchronous function at the point where you are in the code, you should use create_task , instead of await . await causes your function to wait for the other to be completed. the whole async mechanism of Python causes other tasks and functions to continue running, but the function that has await is paused waiting for the response of the sub-task, in the same way as in synchronous code.

That is, your code will work - at least this part, if your keyboard function is written as:

def Keyboard(event):    
    print(event.GetKey())


    if event.GetKey() == 'Lcontrol':
        ctypes.windll.user32.LockWorkStation()
    elif event.GetKey() == 'Next': 
        sys.exit(0)
    else:
        loop = asyncio.get_event_loop()
        loop.create_task(picture())
    return False  # Fora do "if": também retorna False quando o sistema sair do "LockWorkStation" acima

async def picture():
   ...

Of course, for this to work it will depend on the rest of the code to start an asyncio event-loop that is working normally - it is not the kiwi default to work with asyncio.

    
19.11.2018 / 13:34
0

I found the solution:

t = threading.Thread(target=picture) #added to queue
t.start()
    
19.11.2018 / 15:26