Как правильно закрыть QtApplication PyQt? - PullRequest
4 голосов
/ 08 мая 2011

Я не знаю в первую очередь о 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)

Ответы [ 2 ]

2 голосов
/ 23 января 2012

Вам нужно обрабатывать QApplication вне тестовых функций, вроде как синглтон (на самом деле это уместно здесь).

Что вы можете сделать, это проверить, является ли QtCore.qApp чем-то (или QApplication.instance () возвращает None или что-то еще), и только затем создать ваше qApp, в противном случае используйте глобальное.

Он не будет уничтожен после вашей функции test (), поскольку PyQt где-то хранит приложение.

Если вы хотите убедиться, что он обрабатывается правильно, просто установите для него лениво инициализированный синглтон.

1 голос
/ 20 декабря 2011

Приложение QApplication должно быть инициализировано только один раз! Он может быть использован любым количеством экземпляров Capture, но вы должны запустить их в основном цикле. Смотри: https://doc.qt.io/qt-4.8/qapplication.html

Вы также можете попробовать "del app" после "app.exec_", но я не уверен в результатах. (Ваш оригинальный код отлично работает в моей системе)

Я бы использовал 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...