【问题标题】:How to handle Ctrl+C in python app with PyQt?如何使用 PyQt 在 python 应用程序中处理 Ctrl+C?
【发布时间】: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,因此我在这两种情况下都可以使用它进行检查。

【问题讨论】:

    标签: python pyqt signals pyqt4


    【解决方案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)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多