如何使用 PyQt 在 python 应用程序中处理 Ctrl+C?

Posted

技术标签:

【中文标题】如何使用 PyQt 在 python 应用程序中处理 Ctrl+C?【英文标题】:How to handle Ctrl+C in python app with PyQt? 【发布时间】:2017-03-15 15:28:10 【问题描述】:

我有一个基于 PyQt4 的 python 2.7 应用程序。我需要在特定的处理程序中处理 Ctrl+C (KeyboardInterrupt, SIGINT, 2)。我看到通过按 Ctrl+C 创建的异常未在 try-except 块中捕获,并且未在处理函数中看到,由 signal 库注册。 Ctrl+C 什么都不做! 我尝试在没有 PyQt 的情况下做同样的事情 - signal 效果很好。 用于测试的代码不使用任何 PyQt API,因此我在这两种情况下都可以使用它进行检查。

【问题讨论】:

【参考方案1】:

CTRL+C 导致向进程发送信号。 Python 捕获信号,并设置一个全局变量,例如 CTRL_C_PRESSED = True。然后,每当 Python 解释器开始执行新的操作码时,它都会看到变量集并引发 KeybordInterrupt。

这意味着 CTRL+C 仅在 Python 解释器正在旋转时才起作用。如果解释器正在执行一个用 C 编写的扩展模块,该模块执行一个长时间运行的操作,CTRL+C 不会中断它,除非它显式地与 Python “合作”。例如:time.sleep() 理论上是一个阻塞操作,但该函数的实现与 Python 解释器“合作”以使 CTRL+C 工作。

这都是设计使然:CTRL+C 是为了“彻底中止”;这就是为什么它被 Python 变成异常的原因(以便在堆栈展开期间执行清理),并且扩展模块对它的支持有点“选择加入”。如果你想完全中止进程,不给它清理的机会,你可以使用 CTRL+。

当 Python 调用 QApplication::exec()(C++ 函数)时,Qt 不知道如何与 Python “合作”以实现 CTRL+C,这就是它不起作用的原因。我认为没有“让它发挥作用”的好方法;您可能想看看是否可以通过全局事件过滤器来处理它。 — 乔瓦尼·巴霍

将这个添加到主程序解决了这个问题。

import signal

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

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

【讨论】:

好的,它允许我在不处理的情况下杀死我的程序。 Ctrl+C可以处理吗? import signalimport sysdef signal_term_handler(signal, frame):print 'got SIGTERM'sys.exit(0)signal.signal(signal.SIGTERM, signal_term_handler)

以上是关于如何使用 PyQt 在 python 应用程序中处理 Ctrl+C?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PyQt4 中使用 QtGui 来收集 Python 程序的输入变量?

如何使 Python PyQT 程序无法在 Windows 中打开命令行

使用 Anaconda Python 的 PyQt Windows 安装程序 - 未找到 PyQt4;如何进行故障排除?

如何在Python PyQt中中断QThread上的脚本执行?

在 PHP 中处理货币值的最佳实践?

如何使用pyqt5在python中制作每周时间表? [关闭]