从控制台(Ctrl-C)杀死时,让我的 PyQt 应用程序退出的正确方法是什么? [英] What is the correct way to make my PyQt application quit when killed from the console (Ctrl-C)?

查看:45
本文介绍了从控制台(Ctrl-C)杀死时,让我的 PyQt 应用程序退出的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我的 PyQt 应用程序从控制台 (Ctrl-C) 终止时退出的正确方法是什么?

What is the correct way to make my PyQt application quit when killed from the console (Ctrl-C)?

目前(我没有做任何特殊的事情来处理 unix 信号),我的 PyQt 应用程序忽略了 SIGINT (Ctrl+C).我希望它表现得很好并在它被杀死时退出.我该怎么做?

Currently (I have done nothing special to handle unix signals), my PyQt application ignores SIGINT (Ctrl+C). I want it to behave nicely and quit when it is killed. How should I do that?

推荐答案

17.4.信号 — 为异步事件设置处理程序

尽管就 Python 用户而言,Python 信号处理程序是异步调用的,但它们只能发生在 Python 解释器的原子"指令之间.这意味着在纯 C 语言实现的长时间计算中到达的信号(例如大文本体上的正则表达式匹配)可能会延迟任意时间.

Although Python signal handlers are called asynchronously as far as the Python user is concerned, they can only occur between the "atomic" instructions of the Python interpreter. This means that signals arriving during long calculations implemented purely in C (such as regular expression matches on large bodies of text) may be delayed for an arbitrary amount of time.

这意味着 Python 无法在 Qt 事件循环运行时处理信号.只有当 Python 解释器运行时(当 QApplication 退出时,或者当从 Qt 调用 Python 函数时)才会调用信号处理程序.

That means Python cannot handle signals while the Qt event loop is running. Only when the Python interpreter run (when the QApplication quits, or when a Python function is called from Qt) the signal handler will be called.

解决方案是使用 QTimer 让解释器不时运行.

A solution is to use a QTimer to let the interpreter run from time to time.

请注意,在下面的代码中,如果没有打开的窗口,则无论用户选择如何,应用程序都会在消息框之后退出,因为 QApplication.quitOnLastWindowClosed() == True.这种行为可以改变.

Note that, in the code below, if there are no open windows, the application will quit after the message box regardless of the user's choice because QApplication.quitOnLastWindowClosed() == True. This behaviour can be changed.

import signal
import sys

from PyQt4.QtCore import QTimer
from PyQt4.QtGui import QApplication, QMessageBox

# Your code here

def sigint_handler(*args):
    """Handler for the SIGINT signal."""
    sys.stderr.write('
')
    if QMessageBox.question(None, '', "Are you sure you want to quit?",
                            QMessageBox.Yes | QMessageBox.No,
                            QMessageBox.No) == QMessageBox.Yes:
        QApplication.quit()

if __name__ == "__main__":
    signal.signal(signal.SIGINT, sigint_handler)
    app = QApplication(sys.argv)
    timer = QTimer()
    timer.start(500)  # You may change this if you wish.
    timer.timeout.connect(lambda: None)  # Let the interpreter run each 500 ms.
    # Your code here.
    sys.exit(app.exec_())

另一种可能的解决方案,正如 LinearOrbit 指出的,是 signal.signal(signal.SIGINT, signal.SIG_DFL),但它不允许自定义处理程序.

Another possible solution, as pointed by LinearOrbit, is signal.signal(signal.SIGINT, signal.SIG_DFL), but it doesn't allow custom handlers.

这篇关于从控制台(Ctrl-C)杀死时,让我的 PyQt 应用程序退出的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆