在while循环外改变while循环的条件变量状态

Change the state of the condition variable for a while loop outside the while loop

我目前正在尝试通过按下一个键(开始)来启动和停止一个 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"

我不确定为什么这不起作用?.. 它应该在我的脑海里?

您可能需要像主循环这样的东西,您可以在其中包含特殊的 while 循环来实现此目的。

更新 1 - 如何? (错)

while True:
    # main loop
    while condition:
        # your special loop
        # do something...
    time.sleep(0.1) # sleep 0.1 seconds

"main loop"是一个无限循环,每0.1秒执行一次包含的指令。因此,您提供了继续检查 condition 的能力。如果 condition == True 您的 "special loop" 将要执行并且在 condition == False 时停止,然后 "main loop" 继续执行。

更新 2 - 实施(正确)

好的,我有 运行 代码,我发现 "main loop" 解决方案不在此处。目前,我有基于多线程的快速、经过测试的解决方案:

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()

问题是,当您调用 listener.join() 时,您的代码此时会等待线程完成。但它永远不会完成,因为它一直在倾听!相反,你想调用 listener.start() 以便线程在后台运行,你可以自由地做你想做的事。

在线程之间共享变量通常不被接受,所以我在这里修改了一个监听器class,它在按下一个键时将变量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 包含延迟,则会使缓冲区过载并导致输出延迟。如果你想要它快,就放一个小的延迟,但不是零。