Ejemplo n.º 1
0
    def exportAsImage(self):
        filename = unicode(QFileDialog.getSaveFileName(self,
                                                       self.tr('Save Model As Image'), '',
                                                       self.tr('PNG files (*.png *.PNG)')))
        if not filename:
            return

        if not filename.lower().endswith('.png'):
            filename += '.png'

        totalRect = QRectF(0, 0, 1, 1)
        for item in self.scene.items():
            totalRect = totalRect.united(item.sceneBoundingRect())
        totalRect.adjust(-10, -10, 10, 10)

        img = QImage(totalRect.width(), totalRect.height(),
                     QImage.Format_ARGB32_Premultiplied)
        img.fill(Qt.white)
        painter = QPainter()
        painter.setRenderHint(QPainter.Antialiasing)
        painter.begin(img)
        self.scene.render(painter, totalRect, totalRect)
        painter.end()

        img.save(filename)
Ejemplo n.º 2
0
        def drawRow(row, sx, sy, last_end=False):
            x = sx
            y = sy
            keys = row
            rw = w - sx
            i = 0
            for k in keys:
                rect = QRectF(x, y, kw, kw)

                if i == len(keys) - 1 and last_end:
                    rect.setWidth(rw)

                p.drawRoundedRect(rect, rx, rx)

                rect.adjust(5, 1, 0, 0)

                p.setPen(QColor(0xff, 0xff, 0xff))
                p.setFont(self.lowerFont)
                p.drawText(rect, Qt.AlignLeft | Qt.AlignBottom,
                           self.regular_text(k))

                p.setPen(QColor(0x9e, 0xde, 0x00))
                p.setFont(self.upperFont)
                p.drawText(rect, Qt.AlignLeft | Qt.AlignTop,
                           self.shift_text(k))

                rw = rw - space - kw
                x = x + space + kw
                i = i + 1

                p.setPen(pen)
            return (x, rw)
Ejemplo n.º 3
0
        def drawRow(row, sx, sy, last_end=False):
            x = sx
            y = sy
            keys = row
            rw = w - sx
            i = 0
            for k in keys:
                rect = QRectF(x, y, kw, kw)

                if i == len(keys) - 1 and last_end:
                    rect.setWidth(rw)

                p.drawRoundedRect(rect, rx, rx)
                p.setPen(Qt.black)

                rect.adjust(5, 1, 0, 0)

                p.setFont(self.lowerFont)
                p.drawText(rect, Qt.AlignLeft | Qt.AlignBottom, self.regular_text(k))

                p.setFont(self.upperFont)
                p.drawText(rect, Qt.AlignLeft | Qt.AlignTop, self.shift_text(k))

                rw = rw - space - kw
                x = x + space + kw
                i = i + 1

                p.setPen(pen)
            return (x, rw)
Ejemplo n.º 4
0
def visible_bounding_rect(items):
    """ Returns the bounding rectangle of all visible items. """

    # initialize with
    min_x = float_info.max
    min_y = float_info.max
    max_x = -float_info.max
    max_y = -float_info.max

    for item in items:
        if item.isVisible():
            itemBounds = item.boundingRect()
            itemTopLeft = item.mapToScene(itemBounds.topLeft())
            itemBottomRight = item.mapToScene(itemBounds.bottomRight())

            if itemTopLeft.x() < min_x:
                min_x = itemTopLeft.x()

            if itemTopLeft.y() < min_y:
                min_y = itemTopLeft.y()

            if itemBottomRight.x() > max_x:
                max_x = itemBottomRight.x()

            if itemBottomRight.y() > max_y:
                max_y = itemBottomRight.y()

    margin = 10
    rect = QRectF(QPointF(min_x, min_y), QPointF(max_x, max_y))
    rect.adjust(-margin, -margin, margin, margin)
    return rect
Ejemplo n.º 5
0
    def exportAsImage(self):
        filename = unicode(
            QFileDialog.getSaveFileName(self,
                                        self.tr('Save Model As Image'), '',
                                        self.tr('PNG files (*.png *.PNG)')))
        if not filename:
            return

        if not filename.lower().endswith('.png'):
            filename += '.png'

        totalRect = QRectF(0, 0, 1, 1)
        for item in self.scene.items():
            totalRect = totalRect.united(item.sceneBoundingRect())
        totalRect.adjust(-10, -10, 10, 10)

        img = QImage(totalRect.width(), totalRect.height(),
                     QImage.Format_ARGB32_Premultiplied)
        img.fill(Qt.white)
        painter = QPainter()
        painter.setRenderHint(QPainter.Antialiasing)
        painter.begin(img)
        self.scene.render(painter, totalRect, totalRect)
        painter.end()

        img.save(filename)
Ejemplo n.º 6
0
def visible_bounding_rect(items):
    """ Returns the bounding rectangle of all visible items. """

    # initialize with
    min_x = float_info.max
    min_y = float_info.max
    max_x = -float_info.max
    max_y = -float_info.max

    for item in items:
        if item.isVisible():
            itemBounds = item.boundingRect()
            itemTopLeft = item.mapToScene(itemBounds.topLeft())
            itemBottomRight = item.mapToScene(itemBounds.bottomRight())

            if (itemTopLeft.x() < min_x):
                min_x = itemTopLeft.x()

            if (itemTopLeft.y() < min_y):
                min_y = itemTopLeft.y()

            if (itemBottomRight.x() > max_x):
                max_x = itemBottomRight.x()

            if (itemBottomRight.y() > max_y):
                max_y = itemBottomRight.y()

    margin = 10
    rect = QRectF(QPointF(min_x, min_y), QPointF(max_x, max_y))
    rect.adjust(-margin, -margin, margin, margin)
    return rect
Ejemplo n.º 7
0
 def boundingRect(self):
     extra = (SfLine.ARROW_WIDTH + SfLine.ARROW_HEAD_LENGTH)/2.0 + 5
     size = QSizeF(self.line().p2().x() - self.line().p1().x(), 
                   self.line().p2().y() - self.line().p1().y())
     rect = QRectF(self.line().p1(), size)
     rect = rect.normalized()
     rect.adjust(-extra, -extra, extra, extra)
     return rect
Ejemplo n.º 8
0
    def paintEvent(self, event):
        QFrame.paintEvent(self, event)
        text = QDateTime.currentDateTime().toString(Qt.SystemLocaleLongDate)
        logicalRect = QRectF(QPointF(0, 0), QSizeF(QFontMetrics(self.font()).size(Qt.TextSingleLine, text)))
        physicalRect, frameWidth = QRectF(self.rect()), self.frameWidth()
        physicalRect.adjust(frameWidth, frameWidth, -frameWidth, -frameWidth)
        scaleForWidth = physicalRect.width() / logicalRect.width()
        scaleForHeight = physicalRect.height() / logicalRect.height()
        logicalRect.moveTo(frameWidth / scaleForWidth , frameWidth / scaleForHeight)

        painter = QStylePainter(self)
        painter.scale(scaleForWidth, scaleForHeight)
        painter.drawText(logicalRect, Qt.AlignCenter, text)
Ejemplo n.º 9
0
    def paintEvent(self, event):
        QFrame.paintEvent(self, event)
        text = QDateTime.currentDateTime().toString(Qt.SystemLocaleLongDate)
        logicalRect = QRectF(
            QPointF(0, 0),
            QSizeF(QFontMetrics(self.font()).size(Qt.TextSingleLine, text)))
        physicalRect, frameWidth = QRectF(self.rect()), self.frameWidth()
        physicalRect.adjust(frameWidth, frameWidth, -frameWidth, -frameWidth)
        scaleForWidth = physicalRect.width() / logicalRect.width()
        scaleForHeight = physicalRect.height() / logicalRect.height()
        logicalRect.moveTo(frameWidth / scaleForWidth,
                           frameWidth / scaleForHeight)

        painter = QStylePainter(self)
        painter.scale(scaleForWidth, scaleForHeight)
        painter.drawText(logicalRect, Qt.AlignCenter, text)
Ejemplo n.º 10
0
    def update(self, zoom_only=False):
        self.update_ticks()
        line_color = self.plot.color(OWPalette.Axis)
        text_color = self.plot.color(OWPalette.Text)
        if not self.graph_line or not self.scene():
            return
        self.line_item.setLine(self.graph_line)
        self.line_item.setPen(line_color)
        if self.title:
            self.title_item.setHtml('<b>' + self.title + '</b>')
            self.title_item.setDefaultTextColor(text_color)
        if self.title_location == AxisMiddle:
            title_p = 0.5
        elif self.title_location == AxisEnd:
            title_p = 0.95
        else:
            title_p = 0.05
        title_pos = self.graph_line.pointAt(title_p)
        v = self.graph_line.normalVector().unitVector()

        dense_text = False
        if hasattr(self, 'title_margin'):
            offset = self.title_margin
        elif self._ticks:
            if self.should_be_expanded():
                offset = 55
                dense_text = True
            else:
                offset = 35
        else:
            offset = 10

        if self.title_above:
            title_pos = title_pos + (v.p2() - v.p1()) * (
                offset + QFontMetrics(self.title_item.font()).height())
        else:
            title_pos = title_pos - (v.p2() - v.p1()) * offset
        ## TODO: Move it according to self.label_pos
        self.title_item.setVisible(self.show_title)
        self.title_item.setRotation(-self.graph_line.angle())
        c = self.title_item.mapToParent(
            self.title_item.boundingRect().center())
        tl = self.title_item.mapToParent(
            self.title_item.boundingRect().topLeft())
        self.title_item.setPos(title_pos - c + tl)

        ## Arrows
        if not zoom_only:
            if self.start_arrow_item:
                self.scene().removeItem(self.start_arrow_item)
                self.start_arrow_item = None
            if self.end_arrow_item:
                self.scene().removeItem(self.end_arrow_item)
                self.end_arrow_item = None

        if self.arrows & AxisStart:
            if not zoom_only or not self.start_arrow_item:
                self.start_arrow_item = QGraphicsPathItem(
                    self.arrow_path, self)
            self.start_arrow_item.setPos(self.graph_line.p1())
            self.start_arrow_item.setRotation(-self.graph_line.angle() + 180)
            self.start_arrow_item.setBrush(line_color)
            self.start_arrow_item.setPen(line_color)
        if self.arrows & AxisEnd:
            if not zoom_only or not self.end_arrow_item:
                self.end_arrow_item = QGraphicsPathItem(self.arrow_path, self)
            self.end_arrow_item.setPos(self.graph_line.p2())
            self.end_arrow_item.setRotation(-self.graph_line.angle())
            self.end_arrow_item.setBrush(line_color)
            self.end_arrow_item.setPen(line_color)

        ## Labels

        n = len(self._ticks)
        resize_plot_item_list(self.label_items, n, QGraphicsTextItem, self)
        resize_plot_item_list(self.label_bg_items, n, QGraphicsRectItem, self)
        resize_plot_item_list(self.tick_items, n, QGraphicsLineItem, self)

        test_rect = QRectF(self.graph_line.p1(),
                           self.graph_line.p2()).normalized()
        test_rect.adjust(-1, -1, 1, 1)

        n_v = self.graph_line.normalVector().unitVector()
        if self.title_above:
            n_p = n_v.p2() - n_v.p1()
        else:
            n_p = n_v.p1() - n_v.p2()
        l_v = self.graph_line.unitVector()
        l_p = l_v.p2() - l_v.p1()
        for i in range(n):
            pos, text, size, step = self._ticks[i]
            hs = 0.5 * step
            tick_pos = self.map_to_graph(pos)
            if not test_rect.contains(tick_pos):
                self.tick_items[i].setVisible(False)
                self.label_items[i].setVisible(False)
                continue
            item = self.label_items[i]
            item.setVisible(True)
            if not zoom_only:
                if self.id in XAxes or getattr(self, 'is_horizontal', False):
                    item.setHtml('<center>' + Qt.escape(text.strip()) +
                                 '</center>')
                else:
                    item.setHtml(Qt.escape(text.strip()))

            item.setTextWidth(-1)
            text_angle = 0
            if dense_text:
                w = min(item.boundingRect().width(), self.max_text_width)
                item.setTextWidth(w)
                if self.title_above:
                    label_pos = tick_pos + n_p * (
                        w + self.text_margin
                    ) + l_p * item.boundingRect().height() / 2
                else:
                    label_pos = tick_pos + n_p * self.text_margin + l_p * item.boundingRect(
                    ).height() / 2
                text_angle = -90 if self.title_above else 90
            else:
                w = min(
                    item.boundingRect().width(),
                    QLineF(self.map_to_graph(pos - hs),
                           self.map_to_graph(pos + hs)).length())
                label_pos = tick_pos + n_p * self.text_margin - l_p * w / 2
                item.setTextWidth(w)

            if not self.always_horizontal_text:
                if self.title_above:
                    item.setRotation(-self.graph_line.angle() - text_angle)
                else:
                    item.setRotation(self.graph_line.angle() - text_angle)

            item.setPos(label_pos)
            item.setDefaultTextColor(text_color)

            self.label_bg_items[i].setRect(item.boundingRect())
            self.label_bg_items[i].setPen(QPen(Qt.NoPen))
            self.label_bg_items[i].setBrush(self.plot.color(OWPalette.Canvas))

            item = self.tick_items[i]
            item.setVisible(True)
            tick_line = QLineF(v)
            tick_line.translate(-tick_line.p1())
            tick_line.setLength(size)
            if self.title_above:
                tick_line.setAngle(tick_line.angle() + 180)
            item.setLine(tick_line)
            item.setPen(line_color)
            item.setPos(self.map_to_graph(pos))
Ejemplo n.º 11
0
    def update(self, zoom_only = False):
        self.update_ticks()
        line_color = self.plot.color(OWPalette.Axis)
        text_color = self.plot.color(OWPalette.Text)
        if not self.graph_line or not self.scene():
            return
        self.line_item.setLine(self.graph_line)
        self.line_item.setPen(line_color)
        if self.title:
            self.title_item.setHtml('<b>' + self.title + '</b>')
            self.title_item.setDefaultTextColor(text_color)
        if self.title_location == AxisMiddle:
            title_p = 0.5
        elif self.title_location == AxisEnd:
            title_p = 0.95
        else:
            title_p = 0.05
        title_pos = self.graph_line.pointAt(title_p)
        v = self.graph_line.normalVector().unitVector()

        dense_text = False
        if hasattr(self, 'title_margin'):
            offset = self.title_margin
        elif self._ticks:
            if self.should_be_expanded():
                offset = 55
                dense_text = True
            else:
                offset = 35
        else:
            offset = 10

        if self.title_above:
            title_pos = title_pos + (v.p2() - v.p1())*(offset + QFontMetrics(self.title_item.font()).height())
        else:
            title_pos = title_pos - (v.p2() - v.p1())*offset
        ## TODO: Move it according to self.label_pos
        self.title_item.setVisible(self.show_title)
        self.title_item.setRotation(-self.graph_line.angle())
        c = self.title_item.mapToParent(self.title_item.boundingRect().center())
        tl = self.title_item.mapToParent(self.title_item.boundingRect().topLeft())
        self.title_item.setPos(title_pos - c + tl)

        ## Arrows
        if not zoom_only:
            if self.start_arrow_item:
                self.scene().removeItem(self.start_arrow_item)
                self.start_arrow_item = None
            if self.end_arrow_item:
                self.scene().removeItem(self.end_arrow_item)
                self.end_arrow_item = None

        if self.arrows & AxisStart:
            if not zoom_only or not self.start_arrow_item:
                self.start_arrow_item = QGraphicsPathItem(self.arrow_path, self)
            self.start_arrow_item.setPos(self.graph_line.p1())
            self.start_arrow_item.setRotation(-self.graph_line.angle() + 180)
            self.start_arrow_item.setBrush(line_color)
            self.start_arrow_item.setPen(line_color)
        if self.arrows & AxisEnd:
            if not zoom_only or not self.end_arrow_item:
                self.end_arrow_item = QGraphicsPathItem(self.arrow_path, self)
            self.end_arrow_item.setPos(self.graph_line.p2())
            self.end_arrow_item.setRotation(-self.graph_line.angle())
            self.end_arrow_item.setBrush(line_color)
            self.end_arrow_item.setPen(line_color)

        ## Labels

        n = len(self._ticks)
        resize_plot_item_list(self.label_items, n, QGraphicsTextItem, self)
        resize_plot_item_list(self.label_bg_items, n, QGraphicsRectItem, self)
        resize_plot_item_list(self.tick_items, n, QGraphicsLineItem, self)

        test_rect = QRectF(self.graph_line.p1(),  self.graph_line.p2()).normalized()
        test_rect.adjust(-1, -1, 1, 1)

        n_v = self.graph_line.normalVector().unitVector()
        if self.title_above:
            n_p = n_v.p2() - n_v.p1()
        else:
            n_p = n_v.p1() - n_v.p2()
        l_v = self.graph_line.unitVector()
        l_p = l_v.p2() - l_v.p1()
        for i in range(n):
            pos, text, size, step = self._ticks[i]
            hs = 0.5 * step
            tick_pos = self.map_to_graph( pos )
            if not test_rect.contains(tick_pos):
                self.tick_items[i].setVisible(False)
                self.label_items[i].setVisible(False)
                continue
            item = self.label_items[i]
            item.setVisible(True)
            if not zoom_only:
                if self.id in XAxes or getattr(self, 'is_horizontal', False):
                    item.setHtml( '<center>' + Qt.escape(text.strip()) + '</center>')
                else:
                    item.setHtml(Qt.escape(text.strip()))

            item.setTextWidth(-1)
            text_angle = 0
            if dense_text:
                w = min(item.boundingRect().width(), self.max_text_width)
                item.setTextWidth(w)
                if self.title_above:
                    label_pos = tick_pos + n_p * (w + self.text_margin) + l_p * item.boundingRect().height()/2
                else:
                    label_pos = tick_pos + n_p * self.text_margin + l_p * item.boundingRect().height()/2
                text_angle = -90 if self.title_above else 90
            else:
                w = min(item.boundingRect().width(), QLineF(self.map_to_graph(pos - hs), self.map_to_graph(pos + hs) ).length())
                label_pos = tick_pos + n_p * self.text_margin - l_p * w/2
                item.setTextWidth(w)

            if not self.always_horizontal_text:
                if self.title_above:
                    item.setRotation(-self.graph_line.angle() - text_angle)
                else:
                    item.setRotation(self.graph_line.angle() - text_angle)

            item.setPos(label_pos)
            item.setDefaultTextColor(text_color)

            self.label_bg_items[i].setRect(item.boundingRect())
            self.label_bg_items[i].setPen(QPen(Qt.NoPen))
            self.label_bg_items[i].setBrush(self.plot.color(OWPalette.Canvas))

            item = self.tick_items[i]
            item.setVisible(True)
            tick_line = QLineF(v)
            tick_line.translate(-tick_line.p1())
            tick_line.setLength(size)
            if self.title_above:
                tick_line.setAngle(tick_line.angle() + 180)
            item.setLine( tick_line )
            item.setPen(line_color)
            item.setPos(self.map_to_graph(pos))