Error about " module object has no attribute 'QStringList' "

ofenerci at hotmail.com ofenerci at hotmail.com
Sun Mar 17 12:15:26 EDT 2013


Dear List,

I have been working on restructured text(rest) documents and found a nice application which makes viewing the rest documents easy. It is a  web browser especially suited for Sphinx documents. 

When I run the code, I get error which says that :

----------------->-----------------------
Traceback (most recent call last):
  File "/usr/local/bin/doc-watch", line 73, in <lambda>
    self.wb.urlChanged.connect(lambda: self.url.setCompleter(QtGui.QCompleter(QtCore.QStringList([QtCore.QString(i.url().toString()) for i in self.wb.history().items()]), caseSensitivity = QtCore.Qt.CaseInsensitive)))
AttributeError: 'module' object has no attribute 'QStringList'
--------------------<--------------------

I am running python2.7 on Debian Testing. I appreciate any help to shed any light on this error. The code is following:

Best Regards,
Ozhan Fenerci



#!/usr/bin/env python
#
# Copyright (C) 2012 Vinay Sajip. Licensed under the MIT license.
#
# Based on Roberto Alsina's 128-line web browser, see
#
# http://lateral.netmanagers.com.ar/weblog/posts/BB948.html
#
import json
import os
import subprocess
import sys
import tempfile
from urllib import pathname2url

import sip
sip.setapi("QString", 2)
sip.setapi("QVariant", 2)

from PyQt4 import QtGui, QtCore, QtWebKit, QtNetwork


settings = QtCore.QSettings("Vinay Sajip", "DocWatch")

class Watcher(QtCore.QThread):
    """
    A watcher which looks for source file changes, builds the documentation,
    and notifies the browser to refresh its contents
    """
    def run(self):
        self._stop = False
        watch_command = 'inotifywait -rq -e close_write --exclude \'"*.html"\' .'.split()
        make_command = 'make html'.split()
        while not self._stop:
            # Perhaps should put notifier access in a mutex - not bothering yet
            self.notifier = subprocess.Popen(watch_command)
            self.notifier.wait()
            if self._stop:
                break
            subprocess.call(make_command)
            # Refresh the UI ...
            self.parent().changed.emit()

    def stop(self):
        self._stop = True
        # Perhaps should put notifier access in a mutex - not bothering for now
        if self.notifier.poll() is None:    # not yet terminated ...
            self.notifier.terminate()

class MainWindow(QtGui.QMainWindow):
    """
    A browser intended for viewing HTML documentation generated by Sphinx.
    """
    changed = QtCore.pyqtSignal()

    def __init__(self, url):
        QtGui.QMainWindow.__init__(self)
        self.sb=self.statusBar()

        self.pbar = QtGui.QProgressBar()
        self.pbar.setMaximumWidth(120)
        self.wb=QtWebKit.QWebView(loadProgress = self.pbar.setValue, loadFinished = self.pbar.hide, loadStarted = self.pbar.show, titleChanged = self.setWindowTitle)
        self.setCentralWidget(self.wb)

        self.tb=self.addToolBar("Main Toolbar")
        for a in (QtWebKit.QWebPage.Back, QtWebKit.QWebPage.Forward, QtWebKit.QWebPage.Reload):
            self.tb.addAction(self.wb.pageAction(a))

        self.url = QtGui.QLineEdit(returnPressed = lambda:self.wb.setUrl(QtCore.QUrl.fromUserInput(self.url.text())))
        self.tb.addWidget(self.url)

        self.wb.urlChanged.connect(lambda u: self.url.setText(u.toString()))
        self.wb.urlChanged.connect(lambda: self.url.setCompleter(QtGui.QCompleter(QtCore.QStringList([QtCore.QString(i.url().toString()) for i in self.wb.history().items()]), caseSensitivity = QtCore.Qt.CaseInsensitive)))

        self.wb.statusBarMessage.connect(self.sb.showMessage)
        self.wb.page().linkHovered.connect(lambda l: self.sb.showMessage(l, 3000))

        self.search = QtGui.QLineEdit(returnPressed = lambda: self.wb.findText(self.search.text()))
        self.search.hide()
        self.showSearch = QtGui.QShortcut("Ctrl+F", self, activated = lambda: (self.search.show() , self.search.setFocus()))
        self.hideSearch = QtGui.QShortcut("Esc", self, activated = lambda: (self.search.hide(), self.wb.setFocus()))

        self.quit = QtGui.QShortcut("Ctrl+Q", self, activated = self.close)
        self.zoomIn = QtGui.QShortcut("Ctrl++", self, activated = lambda: self.wb.setZoomFactor(self.wb.zoomFactor()+.2))
        self.zoomOut = QtGui.QShortcut("Ctrl+-", self, activated = lambda: self.wb.setZoomFactor(self.wb.zoomFactor()-.2))
        self.zoomOne = QtGui.QShortcut("Ctrl+=", self, activated = lambda: self.wb.setZoomFactor(1))
        self.wb.settings().setAttribute(QtWebKit.QWebSettings.PluginsEnabled, True)

        self.sb.addPermanentWidget(self.search)
        self.sb.addPermanentWidget(self.pbar)
        
        self.load_settings()

        self.wb.load(url)
        self.watcher = Watcher(self)
        
        self.changed.connect(self.wb.reload)

        self.watcher.start()

    def load_settings(self):
        settings.beginGroup('mainwindow')
        pos = settings.value('pos')
        size = settings.value('size')
        if isinstance(pos, QtCore.QPoint):
            self.move(pos)
        if isinstance(size, QtCore.QSize):
            self.resize(size)
        settings.endGroup()

    def save_settings(self):
        settings.beginGroup('mainwindow')
        settings.setValue('pos', self.pos())
        settings.setValue('size', self.size())
        settings.endGroup()
    
    def closeEvent(self, event):
        self.save_settings()
        self.watcher.stop()

if __name__ == "__main__":
    if not os.path.isdir('build'):
        # very simplistic sanity check. Works for me, as I generally use
        # sphinx-quickstart defaults
        print('You must run this application from a Sphinx directory containing build')
        rc = 1
    else:
        app=QtGui.QApplication(sys.argv)
        path = os.path.join('build', 'html', 'index.html')
        url = 'file:///' + pathname2url(os.path.abspath(path))
        url = QtCore.QUrl(url)
        wb=MainWindow(url)
        wb.show()
        rc = app.exec_()
    sys.exit(rc)        



More information about the Python-list mailing list