Beispiel #1
0
    def draw(self, page, painter, key, tile, paperColor=None):
        """Draw a tile on the painter.

        The painter is already at the right position and rotation.
        For the Poppler page and renderer, draw() is only used for printing.
        (See AbstractPage.print().)

        """
        source = self.map(key, page.pageRect()).mapRect(
            QRectF(*tile)).toRect()  # rounded
        target = QRectF(0, 0, tile.w, tile.h)
        if key.rotation & 1:
            target.setSize(target.size().transposed())

        doc = page.document
        p = doc.page(page.pageNumber)

        with self.setup(doc, self.printRenderBackend, paperColor):
            if self.printRenderBackend == popplerqt5.Poppler.Document.ArthurBackend:
                # Poppler's Arthur backend removes the current transform from
                # the painter (it sets a default CTM, instead of combining it
                # with the current transform). We let Poppler draw on a QPicture,
                # and draw that on our painter.
                pic = QPicture()
                p.renderToPainter(QPainter(pic), page.dpi, page.dpi,
                                  source.x(), source.y(), source.width(),
                                  source.height())
                # our resolution could be different, scale accordingly
                painter.save()
                painter.scale(
                    pic.logicalDpiX() / painter.device().logicalDpiX(),
                    pic.logicalDpiY() / painter.device().logicalDpiY())
                pic.play(painter)
                painter.restore()
            else:
                # Make an image exactly in the printer's resolution
                m = painter.transform()
                r = m.mapRect(source)  # see where the source ends up
                w, h = r.width(), r.height()
                if m.m11() == 0:
                    w, h = h, w  # swap if rotation & 1  :-)
                # now we know the scale from our dpi to the paintdevice's logicalDpi!
                hscale = w / source.width()
                vscale = h / source.height()
                s = QTransform().scale(hscale, vscale).mapRect(source)
                dpiX = page.dpi * hscale
                dpiY = page.dpi * vscale
                img = p.renderToImage(dpiX, dpiY, s.x(), s.y(), s.width(),
                                      s.height())
                painter.drawImage(target, img, QRectF(img.rect()))
Beispiel #2
0
 def paintEvent(self, QPaintEvent):
     pic = QPicture()
     painter = QPainter(pic)
     getModuleAttrDict(Client.gameObject.module)['paintGame'](painter)
     painter.end()
     painter.begin(self)
     bRect = pic.boundingRect()
     self.sizeHint_ = bRect.size()
     painter.setWindow(bRect)
     painter.setViewTransformEnabled(True)
     width = self.width()
     height = self.height()
     if width * bRect.height() < height * bRect.width():
         pheight = (width * bRect.height()) / bRect.width()
         painter.setViewport(0, (height - pheight) / 2, width, pheight)
     else:
         pwidth = (height * bRect.width()) / bRect.height()
         painter.setViewport((width - pwidth) / 2, 0, pwidth, height)
     self.invTrafo = painter.combinedTransform().inverted()[0]
     pic.play(painter)
Beispiel #3
0
class PictureWidget(QWidget):
    """ Generic widget using a QPicture as a paint buffer. """

    def __init__(self, *args) -> None:
        super().__init__(*args)
        self._picture = QPicture()  # Last saved picture rendering.

    def __enter__(self) -> QPicture:
        """ Reset the current picture, size it to match the widget, and return it for rendering. """
        self._picture = picture = QPicture()
        rect = QRect()
        rect.setSize(self.size())
        picture.setBoundingRect(rect)
        return picture

    def __exit__(self, *_) -> None:
        """ Repaint the widget after rendering is complete. """
        self.update()

    def paintEvent(self, *_) -> None:
        """ Paint the saved picture on this widget when GUI repaint occurs. """
        with QPainter(self) as p:
            self._picture.play(p)

    # should be inherited from a: """ Mixin to send a signal on a context menu request (right-click). """

    contextMenuRequest = pyqtSignal([QPoint])

    def contextMenuEvent(self, event:QContextMenuEvent) -> None:
        pos = event.globalPos()
        self.contextMenuRequest.emit(pos)

    # should be inherited from a: """ Mixin to send a signal on any widget size change. """

    resized = pyqtSignal()

    def resizeEvent(self, *_) -> None:
        self.resized.emit()
Beispiel #4
0
class BarGraphItem(pg.PlotItem):
    """BarGraphItem"""
    def __init__(self,
                 x=None,
                 y=None,
                 *,
                 width=1.0,
                 pen=None,
                 brush=None,
                 name=None,
                 parent=None):
        """Initialization."""
        super().__init__(name=name, parent=parent)

        self._x = None
        self._y = None

        if width > 1.0 or width <= 0:
            width = 1.0
        self._width = width

        if pen is None and brush is None:
            self._pen = FColor.mkPen(None)
            self._brush = FColor.mkBrush('b')
        else:
            self._pen = FColor.mkPen(None) if pen is None else pen
            self._brush = FColor.mkBrush(None) if brush is None else brush

        self.setData(x, y)

    def setData(self, x, y):
        """Override."""
        self._parseInputData(x, y)
        self.updateGraph()

    def data(self):
        """Override."""
        return self._x, self._y

    def _prepareGraph(self):
        """Override."""
        self._graph = QPicture()
        p = QPainter(self._graph)
        p.setPen(self._pen)
        p.setBrush(self._brush)

        x, y = self.transformedData()
        # Now it works for bar plot with equalized gaps
        # TODO: extend it
        if len(x) > 1:
            width = self._width * (x[1] - x[0])
        else:
            width = self._width

        for px, py in zip(x, y):
            p.drawRect(QRectF(px - width / 2, 0, width, py))

        p.end()

    def paint(self, p, *args):
        """Override."""
        if self._graph is None:
            self._prepareGraph()
        self._graph.play(p)

    def boundingRect(self):
        """Override."""
        return QRectF(super().boundingRect())

    def drawSample(self, p):
        """Override."""
        p.setBrush(self._brush)
        p.setPen(self._pen)
        # Legend sample has a bounding box of (0, 0, 20, 20)
        p.drawRect(QRectF(2, 2, 18, 18))
Beispiel #5
0
class BarGraphItem(pg.GraphicsObject):
    """BarGraphItem"""
    def __init__(self, x=None, y=None, *, width=1.0, pen=None, brush=None):
        """Initialization."""
        super().__init__()

        self._picture = None

        self._x = None
        self._y = None

        if width > 1.0 or width <= 0:
            width = 1.0
        self._width = width

        if pen is None and brush is None:
            self._pen = FColor.mkPen(None)
            self._brush = FColor.mkBrush('b')
        else:
            self._pen = FColor.mkPen(None) if pen is None else pen
            self._brush = FColor.mkBrush(None) if brush is None else brush

        self.setData(x, y)

    def setData(self, x, y):
        """PlotItem interface."""
        self._x = [] if x is None else x
        self._y = [] if y is None else y

        if len(self._x) != len(self._y):
            raise ValueError("'x' and 'y' data have different lengths!")

        self._picture = None
        self.update()
        self.informViewBoundsChanged()

    def drawPicture(self):
        self._picture = QPicture()
        p = QPainter(self._picture)
        p.setPen(self._pen)
        p.setBrush(self._brush)

        # Now it works for bar plot with equalized gaps
        # TODO: extend it
        if len(self._x) > 1:
            width = self._width * (self._x[1] - self._x[0])
        else:
            width = self._width

        for x, y in zip(self._x, self._y):
            p.drawRect(QRectF(x - width/2, 0, width, y))

        p.end()
        self.prepareGeometryChange()

    def paint(self, painter, *args):
        """Override."""
        if self._picture is None:
            self.drawPicture()
        self._picture.play(painter)

    def boundingRect(self):
        """Override."""
        if self._picture is None:
            self.drawPicture()
        return QRectF(self._picture.boundingRect())