如何正确关闭 PyQt 的 QtApplication? [英] How do I shut down PyQt's QtApplication correctly?

查看:87
本文介绍了如何正确关闭 PyQt 的 QtApplication?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道 Qt 的第一件事,但我正试图厚颜无耻地从其他地方借用代码 (http://lateral.netmanagers.com.ar/weblog/posts/BB901.html#disqus_thread).;)

I don't know the first thing about Qt, but I'm trying to be cheeky and borrow code from elsewhere (http://lateral.netmanagers.com.ar/weblog/posts/BB901.html#disqus_thread). ;)

我有问题.当我第一次运行 test() 时,一切正常.但是,当我第二次运行它时,我遇到了令人讨厌的段错误.我怀疑问题是我没有正确结束 qt 的东西.我应该对这个程序进行哪些更改以使其多次运行?提前致谢!

I have a problem. When I run test() the first time, everything works swimmingly. However, when I run it the second time, I get nasty segfaults. I suspect that the problem is that I'm not ending the qt stuff correctly. What should I change about this program to make it work multiple times? Thanks in advance!

from PyQt4 import QtCore, QtGui, QtWebKit
import logging

logging.basicConfig(level=logging.DEBUG)

class Capturer(object):
    """A class to capture webpages as images"""

    def __init__(self, url, filename, app):
        self.url = url
        self.app = app
        self.filename = filename
        self.saw_initial_layout = False
        self.saw_document_complete = False

    def loadFinishedSlot(self):
        self.saw_document_complete = True
        if self.saw_initial_layout and self.saw_document_complete:
            self.doCapture()

    def initialLayoutSlot(self):
        self.saw_initial_layout = True
        if self.saw_initial_layout and self.saw_document_complete:
            self.doCapture()

    def capture(self):
        """Captures url as an image to the file specified"""
        self.wb = QtWebKit.QWebPage()
        self.wb.mainFrame().setScrollBarPolicy(
            QtCore.Qt.Horizontal, QtCore.Qt.ScrollBarAlwaysOff)
        self.wb.mainFrame().setScrollBarPolicy(
            QtCore.Qt.Vertical, QtCore.Qt.ScrollBarAlwaysOff)
        self.wb.loadFinished.connect(self.loadFinishedSlot)
        self.wb.mainFrame().initialLayoutCompleted.connect(
            self.initialLayoutSlot)
        logging.debug("Load %s", self.url)
        self.wb.mainFrame().load(QtCore.QUrl(self.url))

    def doCapture(self):
        logging.debug("Beginning capture")
        self.wb.setViewportSize(self.wb.mainFrame().contentsSize())
        img = QtGui.QImage(self.wb.viewportSize(), QtGui.QImage.Format_ARGB32)
        painter = QtGui.QPainter(img)
        self.wb.mainFrame().render(painter)
        painter.end()
        img.save(self.filename)
        self.app.quit()

def test():
    """Run a simple capture"""
    app = QtGui.QApplication([])
    c = Capturer("http://www.google.com", "google.png", app)
    c.capture()
    logging.debug("About to run exec_")
    app.exec_()

DEBUG:root:Load http://www.google.com
QObject::connect: Cannot connect (null)::configurationAdded(QNetworkConfiguration) to QNetworkConfigurationManager::configurationAdded(QNetworkConfiguration)
QObject::connect: Cannot connect (null)::configurationRemoved(QNetworkConfiguration) to QNetworkConfigurationManager::configurationRemoved(QNetworkConfiguration)
QObject::connect: Cannot connect (null)::configurationUpdateComplete() to QNetworkConfigurationManager::updateCompleted()
QObject::connect: Cannot connect (null)::onlineStateChanged(bool) to QNetworkConfigurationManager::onlineStateChanged(bool)
QObject::connect: Cannot connect (null)::configurationChanged(QNetworkConfiguration) to QNetworkConfigurationManager::configurationChanged(QNetworkConfiguration)

Process Python segmentation fault (this last line is comes from emacs)

推荐答案

你需要在测试函数之外处理 QApplication,有点像一个单例(这里实际上很合适).

You need to handle the QApplication outside of the test functions, sort of like a singleton (it's actually appropriate here).

您可以做的是检查 QtCore.qApp 是否是某个东西(或者 QApplication.instance() 是否返回 None 或其他东西),然后才创建您的 qApp,否则,使用全局的.

What you can do is to check if QtCore.qApp is something (or if QApplication.instance() returns None or something else) and only then create your qApp, otherwise, use the global one.

它不会在你的 test() 函数之后被销毁,因为 PyQt 将应用程序存储在某个地方.

It will not be destroyed after your test() function since PyQt stores the app somewhere.

如果你想确保它被正确处理,只需为它设置一个延迟初始化的单例.

If you want to be sure it's handled correctly, just setup a lazily initialized singleton for it.

这篇关于如何正确关闭 PyQt 的 QtApplication?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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