我目前正在尝试通过按下一个键(开始)并通过松开键来启动和停止一个while循环。
所以像这样:
from pynput import keyboard
global condition
condition = False
def on_press(key):
global condition
if key == keyboard.Key.cmd_r:
print('pressed cmd_r'.format(key))
condition = True
else:
print('incorrect character {0}, press cmd_r'.format(key))
def on_release(key):
global condition
print('{0} released'.format(key))
if key == keyboard.Key.cmd_r:
condition = False
#keyboard.Listener.stop
#return False
with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()
while condition==True:
print "Condition true"
我不确定为什么这不起作用?.. 它应该在我的脑海中吗?
问题是,当您调用listener.join()
时,您的代码此时会等待线程完成。但它永远不会完成,因为它总是在倾听!相反,您希望调用listener.start()
以便线程在后台运行,并且您可以自由地执行所需的操作。
线程之间共享变量通常不被接受,因此在这里我创建了一个修改后的侦听器类,该类在按下键时将变量key_pressed
关联到自身,并在释放时None
。然后,您可以随时通过调用listener.key_pressed
在单独的循环中检查此变量,从而对它执行所需的操作
from pynput import keyboard
import time
class MyListener(keyboard.Listener):
def __init__(self):
super(MyListener, self).__init__(self.on_press, self.on_release)
self.key_pressed = None
def on_press(self, key):
self.key_pressed = key
def on_release(self, key):
self.key_pressed = None
listener = MyListener()
listener.start()
while True:
time.sleep(0.1)
print listener.key_pressed
请注意,如果不如上所述包含time.sleep
延迟,则会使缓冲区过载并导致输出延迟。如果你想要快速,只需放一个小的延迟,但不是零。
您可能需要类似主循环的东西,您可以在其中包含特殊的 while 循环来实现这一点。
更新 1 - 如何?(错)
while True:
# main loop
while condition:
# your special loop
# do something...
time.sleep(0.1) # sleep 0.1 seconds
"主循环"是一个无限循环,每0.1秒执行一次包含的指令。因此,您提供了继续检查condition
的能力。如果condition == True
您的"特殊循环"将要执行,并且在condition == False
时停止,然后"主循环"继续执行。
更新 2 - 实现(正确)
好的,我已经运行了代码,我看到"主循环"解决方案不在这里。目前,我有基于多线程的快速,经过测试的解决方案:
import time
import threading
from pynput import keyboard
condition = False
def my_special_task():
global condition
while condition:
print("condition = %s" % condition)
time.sleep(0.1)
def on_press(key):
global condition
if key == keyboard.Key.ctrl_r:
print('Pressed ctrl_r')
condition = True
thread = threading.Thread(target=my_special_task)
thread.start()
else:
print("Incorrect KEY: %s, press ctrl_r instead" % key)
def on_release(key):
global condition
print("%s released" % key)
if key == keyboard.Key.ctrl_r:
condition = False
with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()