如何在PyQt的Python应用程序中处理Ctrl+C?

3
我有一个基于PyQt4的Python 2.7应用程序。我需要在特定处理程序中处理Ctrl+C(KeyboardInterruptSIGINT,2)。我发现通过按下Ctrl+C创建的异常没有被try-except块捕获,也没有在signal库注册的处理函数中看到。Ctrl+C什么都不做!
我尝试过不使用PyQt来完成相同的操作 - signal工作正常。
用于测试的代码不使用任何PyQt API,因此我可以在两种情况下进行检查。
1个回答

2
CTRL+C会向进程发送一个信号。Python捕获该信号,并设置一个全局变量,类似于CTRL_C_PRESSED = True。然后,每当Python解释器执行新的操作码时,它会看到设置的变量并引发KeybordInterrupt。
这意味着只有当Python解释器在运行时,CTRL+C才起作用。如果解释器正在执行由C编写的扩展模块,该模块执行长时间运行的操作,则CTRL+C不会中断它,除非它明确地与Python“合作”。例如:time.sleep()理论上是一个阻塞操作,但该函数的实现与Python解释器“合作”,使CTRL+C起作用。
这都是有意设计的:CTRL+C旨在进行“干净的中止”;这就是为什么Python将其转换为异常(以便在堆栈展开期间执行清理),并且扩展模块对其的支持有点“选择性”。如果您想完全中止进程而不给它清理的机会,可以使用CTRL+。
当Python调用QApplication :: exec()(C ++函数)时,Qt不知道如何与Python“合作”以进行CTRL+C,这就是为什么它不起作用的原因。我认为没有很好的“使其工作”的方法;您可能希望查看是否可以通过全局事件过滤器来处理它。 - Giovanni Bajo
将此添加到主程序中解决了问题。
import signal

signal.signal(signal.SIGINT, signal.SIG_DFL)

我不确定这与解释有什么关系。


好的,它允许我在不处理的情况下终止程序。有可能处理Ctrl+C吗? - Jury
导入信号 导入系统def 信号终止处理器(信号, 帧): 打印 '收到SIGTERM信号' sys.exit(0)signal.signal(signal.SIGTERM, 信号终止处理器) - EAK TEAM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接