退出信号未在 PyQt 中捕获

Posted

技术标签:

【中文标题】退出信号未在 PyQt 中捕获【英文标题】:Exit signal not being caught in PyQt 【发布时间】:2011-10-11 17:28:44 【问题描述】:

编写脚本以将任意 html 呈现为图像,并使用 PyQt。我很困惑为什么我的QApplication.exit 电话没有让QApplication.exec_ 返回。对此有何想法?

class ScreenshotterApplication(QApplication):

    def __init__(self, args, html):
        QApplication.__init__(self, args)

        self.html = html

        self.browser = QWebView()
        self.browser.resize(0, 0)
        self.browser.loadFinished.connect(self.save)
        self.browser.loadProgress.connect(self.progress)

    def render(self):
        self.browser.setHtml(self.html)

    def progress(self, progress):
        print '%d%%' % progress

    def save(self, finished):
        success = False
        if finished:
            print 'saving...'
            # ... snip ...

            success = pixmap.save('screenshot.png')
            if success:
                print 'saved as "screenshot.png"'

        QApplication.exit(0 if success else 1)

    def exec_(self, *args, **kwargs):
        self.render()
        super(QApplication, self).exec_(*args, **kwargs)

def take_screenshot(html):
    app = ScreenshotterApplication(sys.argv, html)
    return app.exec_()

if __name__ == "__main__":
    print take_screenshot('<h1 style="width: 500px">Hello, World!</h1>')

【问题讨论】:

哦,它以前工作过。我不确定我是否更改了某些内容,但无论我现在做什么,它都不会正确退出。 【参考方案1】:

QApplication.exit 告诉应用程序离开主事件循环,即尽快从exec_() 返回。

您的问题是一小段静态 HTML 很容易检索和呈现,当调用 setHtml 时 QtWebKit 就可以做到这一点。没有延迟或后台处理,一切都在 setHtml 返回之前完成。所以,save 被调用主循环开始之前(即在exec_ 被调用之前)。

这就像当你不在一个函数中时写return - 除了如果循环没有运行,Qt 会安静地忽略exit

解决方案:在您的 connect 调用中使用 QueuedConnection 来强制信号排队,并在事件循环开始时传递。当然,如果循环正在已经在运行,这也可以工作。

self.browser.loadFinished.connect(self.save, Qt.QueuedConnection)

【讨论】:

以上是关于退出信号未在 PyQt 中捕获的主要内容,如果未能解决你的问题,请参考以下文章

发送 stderr/stdout 消息到函数并捕获退出信号

c++ signal 信号退出

捕获Ctrl + C中断 优雅的退出程序 golang

捕获 TERM 并发送 QUIT 后 Heroku 上的独角兽退出超时

Swift app中的Crash捕获与处理

pyqt5异常退出无提示信息