2  Implementation Notes

2.1  Qt Programming Notes

The imageviewer module demonstrates:

  • Using QGraphicsView to implement zooming & panning of a QPixmap. This works much faster for large images at high zoom levels than PyQt4\examples\widgets\imageviewer.pyw which uses a QLabel. The Qt documentation for the slower ImageViewer example is at the nokia website.

  • Keeping track of scroll and view transform changes so other classes can implement synchronized zooming and panning of multiple views.

  • Zooming by Ctrl+Mouse wheel rolling in SynchableGraphicsView.wheelEvent() (QGraphicsView already handles vertical scrolling by rolling the mouse wheel, and horizontal scrolling via Alt+Mouse wheel rolling)

The mdiimageviewer module demonstrates:

2.2  PyQt Programming Notes

The following is done to use the more pythonic PyQt API version 2 whether or not you are using Python 2 or Python 3:

import sip
sip.setapi('QDate', 2)
sip.setapi('QTime', 2)
sip.setapi('QDateTime', 2)
sip.setapi('QUrl', 2)
sip.setapi('QTextStream', 2)
sip.setapi('QVariant', 2)
sip.setapi('QString', 2)

I use the new-style signal/slot mechanism:

self._mdiArea.subWindowActivated.connect(self.subWindowActivated)

rather than the older mechanism:

QtCore.QObject.connect(self._mdiArea, QtCore.SIGNAL("subWindowActivated()"), self, QtCore.SLOT("subWindowActivated()"))

I used pyrcc4 to convert a Qt resource collection file icons.qrc into icons_rc.py which can be imported into any python file. For example the icon exit.png can then be referenced simply by doing:

import icons_rc
...
self._exitAct = QtGui.QAction(
    QtGui.QIcon(':/exit.png'),
    "E&xit", self,
    shortcut=QtGui.QKeySequence.Quit,
    statusTip="Exit the application",
    triggered=QtGui.qApp.closeAllWindows)

2.3  Python Programming Notes

The following is done to allow Python 3 syntax even when running Python 2.6+:

from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from future_builtins import *

In theory these programs should work equally well under Python 3 but that hasn’t been tested yet.

2.4  Sphinx Documentation Notes

I’ve written all the project documentation (including these web pages) using Sphinx — the source files can be found on here.

The Sphinx techniques demonstrated are:

  • Generating an “orphan” Home page that uses a custom sidebar.

  • Using the autodoc extension to generate the module documentation.

  • Using the inheritance diagram extension to add inheritance diagrams to the module documentation.

  • Using the extlinks extension to shorten references to the PyQt v4 - Python Bindings for Qt v4: Reference Guide and the Qt Class Documentation.

  • Creating a custom theme (based of the default theme) to have a custom footer with the Creative Commons Attribution 3.0 Licence & logo rather than a copyright notice. I also have a custom css file to style some elements differently than the defaults.

  • Using a global Table of Contents in the sidebar navigation panel with the current page indicated with a yellowish bullet. Most of the sites I’ve seen use the local TOC which means you have to jump back to their separate Table of Contents page to get a site overview.

  • Using the rst_prolog conf.py setting to create a custom role that can be used in any of the source directory’s .rst files.

  • Using the rst_prolog conf.py setting to create quick replacements for common Qt Class documentation links. For example, |QGraphicsView| generates the following link: QGraphicsView. These replacements even work inside Python docstrings.

2.5  Project Hosting on GitHub Notes

You can directly use Sphinx generated pages as GitHub Pages, but as the “Using Jekyll For Complex Layouts” section explains:

“As of December 27, 2009, you can completely opt-out of Jekyll processing by creating a file named .nojekyll in the root of your pages repo and pushing that to GitHub. This should only be necessary if your site uses directories that begin with an underscore, as Jekyll sees these as special dirs and does not copy them to the final destination.”

Since Sphinx generates a number of subdirectories that start with _ in its build directory, adding .nojekyll is thus required.