def _init_images(self):
     A, = 'A'.encode('ascii')
     gs = Qt.QGraphicsScene()
     sti = Qt.QGraphicsSimpleTextItem()
     sti.setFont(Qt.QFont('Courier', pointSize=24, weight=Qt.QFont.Bold))
     gs.addItem(sti)
     self.images = []
     for char in range(A, A + 26):
         for i in range(0, 10):
             text = bytes([char]).decode('ascii') + str(i)
             sti.setText(text)
             scene_rect_f = gs.itemsBoundingRect()
             scene_rect = Qt.QRect(
                 0,
                 0,
                 math.ceil(scene_rect_f.width()),
                 math.ceil(scene_rect_f.height()))
             gs.setSceneRect(scene_rect_f)
             buffer = numpy.empty((scene_rect.height(), scene_rect.width(), 4), dtype=numpy.uint8)
             buffer[:] = 255
             qimage = Qt.QImage(sip.voidptr(buffer.ctypes.data), scene_rect.size().width(), scene_rect.size().height(), Qt.QImage.Format_RGBA8888)
             qpainter = Qt.QPainter()
             qpainter.begin(qimage)
             qpainter.setRenderHint(Qt.QPainter.Antialiasing)
             qpainter.setRenderHint(Qt.QPainter.HighQualityAntialiasing)
             gs.render(qpainter)
             qpainter.end()
             self.images.append(Image(buffer.copy(), shape_is_width_height=False, name=text))
 def _update_picture(self):
     if self._picture is None:
         self._picture = Qt.QPicture()
         ppainter = Qt.QPainter()
         with ExitStack() as stack:
             ppainter.begin(self._picture)
             stack.callback(ppainter.end)
             # The Qt API calls required for formatting multiline text such that it can be rendered to
             # a path are private, as can be seen in the implementation of
             # QGraphicsSimpleTextItem::paint, pasted below.  (Specifically, QStackTextEngine is a private
             # component and thus not available through PyQt).
             #
             # void QGraphicsSimpleTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
             # {
             #     Q_UNUSED(widget);
             #     Q_D(QGraphicsSimpleTextItem);
             #
             #     painter->setFont(d->font);
             #
             #     QString tmp = d->text;
             #     tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
             #     QStackTextEngine engine(tmp, d->font);
             #     QTextLayout layout(&engine);
             #
             #     QPen p;
             #     p.setBrush(d->brush);
             #     painter->setPen(p);
             #     if (d->pen.style() == Qt::NoPen && d->brush.style() == Qt::SolidPattern) {
             #         painter->setBrush(Qt::NoBrush);
             #     } else {
             #         QTextLayout::FormatRange range;
             #         range.start = 0;
             #         range.length = layout.text().length();
             #         range.format.setTextOutline(d->pen);
             #         QList<QTextLayout::FormatRange> formats;
             #         formats.append(range);
             #         layout.setAdditionalFormats(formats);
             #     }
             #
             #     setupTextLayout(&layout);
             #     layout.draw(painter, QPointF(0, 0));
             #
             #     if (option->state & (QStyle::State_Selected | QStyle::State_HasFocus))
             #         qt_graphicsItem_highlightSelected(this, painter, option);
             # }
             #
             # We would just use QGraphicsSimpleTextItem directly, but it is not derived from QGraphicsObject, so
             # it lacks the QObject base class required for emitting signals.  It is not possible to add a QObject
             # base to a QGraphicsItem derivative in Python (it can be done in C++ - this is how QGraphicsObject
             # is implemented).
             #
             # Total lack of signal support is not acceptable; it would greatly complicate the task of
             # positioning a non-child item relative to a ContextualInfoItem.
             # 
             # However, it's pretty easy to use that very paint function to generate paint commands that
             # we cache in self._picture, so we do that.  For strings large enough that the relayout
             # performed on each refresh by QGraphicsSimpleTextItem exceeds the CPython interpreter overhead 
             # for initiating the QPicture replay, our paint function is faster.
             #
             # Additionally, QGraphicsTextItem is very featureful, has a QObject base, and would be the first
             # choice, but the one thing it can not do is outline text, so it's out.
             i = Qt.QGraphicsSimpleTextItem(self.contextual_info.value)
             i.setFont(self._font)
             # Disabling brush/pen via setBrush/Pen(Qt.QBrush/Pen(Qt.Qt.NoBrush/Pen)) ought to be more intelligent
             # than disablind via setting to transparent color.  However, using NoBrush or NoPen here seems to
             # cause extreme painting slowdowns on OS X.
             transparent_color = Qt.QColor(Qt.Qt.transparent)
             if self._pen is None or self._brush is None:
                 i.setPen(Qt.QPen(transparent_color) if self._pen is None else self._pen)
                 i.setBrush(Qt.QBrush(transparent_color) if self._brush is None else self._brush)
                 i.paint(ppainter, Qt.QStyleOptionGraphicsItem(), None)
             else:
                 # To ensure that character outlines never obscure the entirety of character interior, outline
                 # is drawn first and interior second.  If both brush and pen are nonempty, Qt draws interior first
                 # and outline second.
                 i.setBrush(Qt.QBrush(transparent_color))
                 i.setPen(self._pen)
                 i.paint(ppainter, Qt.QStyleOptionGraphicsItem(), None)
                 i.setBrush(self._brush)
                 i.setPen(Qt.QPen(transparent_color))
                 i.paint(ppainter, Qt.QStyleOptionGraphicsItem(), None)
             self._bounding_rect = i.boundingRect()