为什么 KeyboardInterrupt 不适用于 Python pyautogui 脚本?退出 program/loop 的替代方法?

Why is KeyboardInterrupt not working for Python pyautogui script? Alternative way to exit program/loop?

我正在尝试完成一个简单的 GUI 自动化程序,它只打开一个网页,然后每 0.2 秒单击一次页面上的特定位置,直到我告诉它停止。我希望我的代码 运行 并无限循环 运行 直到我指定的键绑定中断循环(或整个程序)。我从经典的 KeyboardInterrupt 开始,据说它可以使 CTRL+C 退出程序。这是我的代码:

import webbrowser, pyautogui, time
webbrowser.open('https://example.com/')
print('Press Ctrl-C to quit.')
time.sleep(5)
#pyautogui.moveTo(1061, 881)
try:
    while True:
            time.sleep(0.2)
            pyautogui.click(1061,881)
except KeyboardInterrupt:
    print('\nDone.')

不幸的是,KeyboardInterrupt 和使用 CTRL-C 退出似乎不适用于此脚本(可能是由于 while 循环?)。这会导致循环无限地继续 运行 而无法停止。所以我的问题是:为什么键盘中断不起作用?我在其他脚本中看到过类似的例子。此外,如果 KeyboardInterrupt 不起作用,有没有办法编写一个简单的键绑定以退出 program/loop?

我怀疑这可能与您的活动 window 与脚本不同有关;当您使用 webbrowser、打开网页并单击它时,它会将您的活动 window 移动到网页而不是 Python 控制台。因此 ctrl+c 只会在控制台处于活动状态时生成 KeyboardInterrupt window。您的脚本实际上可能是正确的;但是您的活动 window 不在 Python 上,因此您必须在程序运行时通过单击回到 Python 控制台来测试它。

回答您的评论:不,我不知道有任何其他 "quick" 方法可以做这样的事情。

使用下面的代码

pyautogui.FAILSAFE = True

然后停止,将鼠标移动到屏幕的左上角

我来晚了,但我可以提供一个解决方案,让您可以按 CTRL + C 停止程序。你需要安装 keyboard 模块并使用 keyboard.is_pressed() 来捕捉你按下你想要的键作为标志:

import keyboard


# You program...

while True:
    time.sleep(0.2)
    pyautogui.click(1061,881)

    if keyboard.is_pressed("ctrl+c"):
        break

不过您需要小心,因为程序只会在执行 if 语句时检查您是否按下了按键。如果您的程序运行 10 秒并且您将 if 放在末尾,您将只能每 10 秒退出一次,并且退出时间很短。

我还建议您在等待程序捕获它们时按住按键,以免错过这一刻。

如果您需要立即终止程序而不必总是检查是否按下了 CTRL+C,您可以将它放入一个进程中并在需要时终止它。这有点矫枉过正,也不是推荐的方式,但如果你真的需要它,就在这里。

import pyautogui
import keyboard
import time

from multiprocessing import Process


def execute_program():
    """Long program which you want to interrupt instantly"""

    while True:
        pyautogui.click()
        time.sleep(10)


if __name__ == '__main__':
    # The failsafe allows you to move the cursor on the upper left corner of the screen to terminate the program. 
    # It is STRONGLY RECOMMENDED to keep it True
    pyautogui.FAILSAFE = True

    # Spawn and start the process
    execute_program_process = Process(target=execute_program)
    execute_program_process.start()

    while True:
        if keyboard.is_pressed('ctrl+c'):
            execute_program_process.terminate()
            break

    print('\nDone.')