如何正确关闭 PyQt 的 QtApplication?



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

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

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,有点像单例(这里实际上很合适)。

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

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

如果要确保正确处理它,只需为其设置一个延迟初始化的单例即可。

QApplication 只能初始化一次!它可以由任意数量的捕获实例使用,但您应该在主循环中启动它们。请参阅:https://doc.qt.io/qt-4.8/qapplication.html

您也可以在"app.exec_"之后尝试"del app",但我不确定结果。(您的原始代码在我的系统上运行良好)

我会使用 urllib 而不是 webkit:

import urllib
class Capturer:
    def capture(self, s_url, s_filename):
        s_file_out, httpmessage = urllib.urlretrieve(s_url, s_filename, self.report)
    def report(self, i_count, i_chunk, i_size):
        print('retrived %5d of %5d bytes' % (i_count * i_chunk, i_size))
def test():
    c = Capturer()
    c.capture("http://www.google.com/google.png", "google1.png")
    c.capture("http://www.google.com/google.png", "google2.png")
if __name__ == '__main__':
    test()

最新更新