如何将 pynput.keyboard 运行 作为一个线程?

How do I make pynput.keyboard run as a Thread?

我使用 Pynput 编写了一个脚本来捕获击键,它一直运行良好,直到我想在捕获击键(线程)时每 15 秒截取一次屏幕截图。

我阅读了有关 pynput.keyboard 的文档,看到 A keyboard listener 是 threading.Thread,但我无法做到,我想我设法创建了两个线程,但事实并非如此进入'getKey'功能我不知道为什么。

from PIL import ImageGrab
import time 
from pynput.keyboard import Key, Listener
from pynput import keyboard
import logging
import os 
import threading


def main():
    listener = keyboard.Listener(onpress=getKey)
    listener.start()
    thread2 = threading.Thread(target=takeScreenshot, args=())
    thread2.start()
    thread2.join()


def getKey(key):
    print(key)
    key = fixKey(key)
    file = open('log.txt', 'a')
    file.write(key.replace('\'', '') + '')
    file.close()

def fixKey(key):
    key = str(key)
    if key == 'Key.space':
        return ' '
    elif key == 'Key.enter':
        return '\n'
    return key

def takeScreenshot():
    time.sleep(15)
    image = ImageGrab.grab()
    now = time.strftime("%d-%m-%Y" + ' ' + "%H-%M-%S")
    image.save(now + '.png')

main()

正如我所解释的,它甚至不创建文件 'log.txt' 仅在 15 秒后截取屏幕截图。 谢谢!

这是官方监听器的正确使用方法docs

如果您需要每 15 秒捕获一次屏幕截图,您应该 运行 一个带有 while 循环的线程在后台连续 运行

代码如下:

from PIL import ImageGrab
import time 
from pynput.keyboard import Key, Listener
from pynput import keyboard
import logging
import os 
import threading


def main():
    thread2 = threading.Thread(target=takeScreenshot, args=())
    thread2.start()

    with Listener(on_press=getKey) as listener:
        listener.join()


def getKey(key):
    print(key)
    key = fixKey(key)
    file = open('log.txt', 'a')
    file.write(key.replace('\'', '') + '')
    file.close()

def fixKey(key):
    key = str(key)
    if key == 'Key.space':
        return ' '
    elif key == 'Key.enter':
        return '\n'
    return key

def takeScreenshot():
    # run contineous and take screenshot every 15 seconds
    while True:
        print('taking screenshot')
        image = ImageGrab.grab()
        now = time.strftime("%d-%m-%Y" + ' ' + "%H-%M-%S")
        image.save(now + '.png')
        time.sleep(15)


main()

要以非阻塞方式使用它,您应该这样做:

listener = Listener(on_press=on_press, on_release=on_release,suppress=True)
        listener.start()

这将创建 1 个线程,该线程始终在监听而不会阻塞整个代码(以防您需要执行与键无关的事情),但这也可能最终创建太多线程,因此请确保您只如果它还不存在,请像这样创建它:

from pynput.keyboard import Key, Listener, Controller
listener = None
keyPressed = None

def on_press(key):
    if key == Key.enter:
        global saveFile
        saveFile = True  

def on_release(key):
    global keyPressed
    keyPressed = key.char


def CheckWhichKeyIsPressed():
    global listener

    if listener == None:  
        listener = Listener(on_press=on_press, on_release=on_release,suppress=True)
        listener.start()