退出信号没有被PyQt捕获

编写脚本以将任意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>')

解决方法:

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

您的问题是,一小段静态HTML非常容易检索和呈现,当调用setHtml时,QtWebKit正确地做到了.没有延迟或后台处理,一切都在setHtml返回之前完成.因此,在主循环开始之前(即在调用exec_之前)调用save.

这就像在不使用函数时编写return一样–除了Qt只会在循环未运行的情况下静默退出而已.

解决方案:在connect调用中使用QueuedConnection强制将信号排队,并在事件循环开始时将其传递.当然,如果循环已经在运行,这也将起作用.

self.browser.loadFinished.connect(self.save, Qt.QueuedConnection)
上一篇:c-QSpinBox千位分隔符


下一篇:Reflow、Repaint 性能优化