[PyQt] underlying c/c++ object has been deleted

Victor Noagbodji noagbodjivictor at gmail.com
Mon Aug 3 03:22:25 BST 2009


hi all,

i'm getting this runtime error. at every line with a 'SLOT()' in this
code. i don't really know what is going wrong. i have tried to
translate the webcapture code on qt labs graphics dojo:
http://qt.gitorious.org/qt-labs/graphics-dojo/trees/master/webcapture

following is the entire code. when i remove the QObject connect, it
works but breaks on other 'SLOT()' in the code.

thanks a lot in advance.


#############################################################################
##
## Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
## Contact: Qt Software Information (qt-info at nokia.com)
##
## This file is part of the Graphics Dojo project on Qt Labs.
##
## This file may be used under the terms of the GNU General Public
## License version 2.0 or 3.0 as published by the Free Software Foundation
## and appearing in the file LICENSE.GPL included in the packaging of
## this file.  Please review the following information to ensure GNU
## General Public Licensing requirements will be met:
## http://www.fsf.org/licensing/licenses/info/GPLv2.html and
## http://www.gnu.org/copyleft/gpl.html.
##
## If you are unsure which license is appropriate for your use, please
## contact the sales department at qt-sales at nokia.com.
##
## This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
## WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
##
#############################################################################


import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from PyQt4.QtWebKit import *


qtversion = QT_VERSION_STR.split('.')
not_yet_qt_4_5 = len(qtversion) == 3 and qtversion < (4, 5, 0)


class WebCapture(QObject):

  def __init__(self):
    self.m_zoom = 100
    self.m_percent = 0
    self.m_page = QWebPage()
    self.connect(self.m_page, SIGNAL('loadFinished(bool)'), self.save_result)
    self.connect(self.m_page, SIGNAL('loadProgress(int)'), self.show_progress)

  def load(self, url, zoom, output, width):
    print 'Loading', url.toString()
    self.m_zoom = zoom
    self.m_filename = output
    self.m_page.mainFrame().load(url)
    self.m_page.mainFrame().setScrollBarPolicy(Qt.Vertical,
                                               Qt.ScrollBarAlwaysOff)
    self.m_page.mainFrame().setScrollBarPolicy(Qt.Horizontal,
                                               Qt.ScrollBarAlwaysOff)
    factor = self.m_zoom / 100.0

    if not_yet_qt_4_5:
      self.m_page.setViewportSize(QSize(width, 3 * width / 4) / factor)
    else:
      self.m_page.mainFrame().setZoomFactor(factor)
      self.m_page.setViewportSize(QSize(width, 3 * width / 4))

  def show_progress(self, percent):
    if self.m_percent >= percent:
      return
    while self.m_percent < percent:
      self.m_percent += 1
      sys.stdout.write('#')
      sys.stdout.flush()

  def save_result(self, ok):
    print

    # crude error-checking
    if not ok:
      sys.stderr.write('Failed loading %s' %
                       self.m_page.mainFrame().url().toString())
      self.emit(SIGNAL('done'))
      return

    # create the image for the buffer
    size = self.m_page.mainFrame().contentsSize()
    image = QImage(size, QImage.Format_ARGB32_Premultiplied)
    image.fill(Qt.transparent)

    # render the web page
    p = QPainter(image)
    p.setRenderHint(QPainter.Antialiasing, True)
    p.setRenderHint(QPainter.TextAntialiasing, True)
    p.setRenderHint(QPainter.SmoothPixmapTransform, True)
    self.m_page.setViewportSize(self.m_page.mainFrame().contentsSize())
    self.m_page.mainFrame().render(p)
    p.end()

    if not_yet_qt_4_5:
      # scale, since we don't have full page zoom
      factor = self.m_zoom / 100.0
      image = image.scaled(size * factor,
                           Qt.IgnoreAspectRatio,
                           Qt.SmoothTransformation)

    image.save(self.m_filename)
    self.emit(SIGNAL('done'))


def guess_url_from_string(s):
  urlstr = s.trimmed()
  test = QRegExp('^[a-zA-Z]+\\:.*')

  # check if it looks like a qualified URL. try parsing it and see.
  has_schema = test.exactMatch(urlstr)
  if has_schema:
    url = QUrl(urlstr, QUrl.TolerantMode)
    if url.isValid():
      return url

  # might be a file.
  if QFile.exists(urlstr):
    return QUrl.fromLocalFile(urlstr)

  # might be a shortcut - try to detect schema.
  if not has_schema:
    dot_index = urlstr.indexOf('.')
    if dot_index != -1:
      prefix = urlstr.left(dot_index).toLower()
      schema = prefix if prefix == QString('ftp') else QString('http')
      url = QUrl(schema + QString('://') + urlstr, QUrl.TolerantMode)
      if url.isValid():
        return url

  # fall back to QUrl's own tolerance parser.
  return QUrl(s, QUrl.TolerantMode)


if __name__ == '__main__':
  argc = len(sys.argv)

  if argc < 4 or argc > 5:
    print 'Capture a web page and save it as an image'
    print
    print '  webcapture url zoom outputfile [viewport width]'
    print
    print 'Notes: '
    print '  \'zoom\' specifies the zoom factor in percent, default is 100%'
    print '  \'viewport width\' defaults to 1024 (pixels)'
    print
    print 'Examples: '
    print '  webcapture www.trolltech.com 50 trolltech.png 800'
    print '  webcapture www.nokia.com 25 nokia.png'
    print
    sys.exit(1)

  url = guess_url_from_string(QString(sys.argv[1]))
  zoom = max(10, QString(sys.argv[2]).toInt()[0])
  filename = QString(sys.argv[3])
  width = 1024 if argc < 5 else QString(sys.argv[4]).toInt()[0]

  app = QApplication(sys.argv)
  capture = WebCapture()
  QObject.connect(capture,
                  SIGNAL('done'),
                  QApplication.instance(),
                  SLOT('quit()'))
  capture.load(url, zoom, filename, width)
  sys.exit(app.exec_())

-- 
paul victor noagbodji


More information about the PyQt mailing list