为什么 KeyboardInterrupt 不适用于 Python pyautogui 脚本?退出程序/循环的替代方法?



我正在尝试完成一个简单的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.')

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

使用以下代码

pyautogui.FAILSAFE = True

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

我怀疑它可能与您拥有与脚本不同的活动窗口有关; 当您使用webbrowser时,打开一个网页并单击它,它会将您的活动窗口移动到网页而不是 Python 控制台。因此,仅当控制台是活动窗口时,ctrl+c才会生成KeyboardInterrupt。您的脚本实际上可能是正确的;但是您的活动窗口不在 Python 上,因此您必须在程序运行时单击回 Python 控制台来测试它。

回答你的评论:不,我不知道任何其他"快速"方法来做这样的事情。

我迟到了,但我可以提供一种解决方案,允许您按 CTRL + C 停止程序。您需要安装键盘模块并使用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.')

最新更新