Exemple #1
0
 def paintEvent(self, event=None):
     font = QFont(self.font())
     font.setPointSize(font.pointSize() - 1)
     fm = QFontMetricsF(font)
     fracWidth = fm.width(FractionSlider.WSTRING)
     indent = fm.boundingRect("9").width() / 2.0
     if not X11:
         fracWidth *= 1.5
     span = self.width() - (FractionSlider.XMARGIN * 2)
     value = self.__numerator / float(self.__denominator)
     painter = QPainter(self)
     painter.setRenderHint(QPainter.Antialiasing)
     painter.setRenderHint(QPainter.TextAntialiasing)
     painter.setPen(self.palette().color(QPalette.Mid))
     painter.setBrush(self.palette().brush(QPalette.AlternateBase))
     painter.drawRect(self.rect())
     segColor = QColor(Qt.green).darker(120)
     segLineColor = segColor.darker()
     painter.setPen(segLineColor)
     painter.setBrush(segColor)
     painter.drawRect(FractionSlider.XMARGIN, FractionSlider.YMARGIN, span,
                      fm.height())
     textColor = self.palette().color(QPalette.Text)
     segWidth = span / self.__denominator
     segHeight = fm.height() * 2
     nRect = fm.boundingRect(FractionSlider.WSTRING)
     x = FractionSlider.XMARGIN
     yOffset = segHeight + fm.height()
     for i in range(self.__denominator + 1):
         painter.setPen(segLineColor)
         painter.drawLine(x, FractionSlider.YMARGIN, x, segHeight)
         painter.setPen(textColor)
         y = segHeight
         rect = QRectF(nRect)
         rect.moveCenter(QPointF(x, y + fm.height() / 2.0))
         # painter.drawText(rect, Qt.AlignCenter,
         # QString.number(i))
         painter.drawText(rect, Qt.AlignCenter, str(i))
         y = yOffset
         rect.moveCenter(QPointF(x, y + fm.height() / 2.0))
         painter.drawText(rect, Qt.AlignCenter, str(self.__denominator))
         painter.drawLine(QPointF(rect.left() + indent, y),
                          QPointF(rect.right() - indent, y))
         x += segWidth
     span = int(span)
     y = FractionSlider.YMARGIN - 0.5
     triangle = [
         QPointF(value * span, y),
         QPointF((value * span) + (2 * FractionSlider.XMARGIN), y),
         QPointF((value * span) + FractionSlider.XMARGIN, fm.height())
     ]
     painter.setPen(Qt.yellow)
     painter.setBrush(Qt.darkYellow)
     painter.drawPolygon(QPolygonF(triangle))
    def _drawSuffixIon(self, qp: QPainter, index_reverse: int,
                       metrics_ion: QFontMetricsF, pos_end: QPointF,
                       pos_right: QPointF) -> None:
        """
        Draws existing suffix ion(s) and the right line at this position.

        Parameters
        ----------
        qp : QPainter
            The QPainter class provides functions required to paint within the
            widget

        index_reverse: int
            The position of the suffix ion(s) within the peptide. The
            positions are in reverse order compared to the prefix ion(s)

        metrics_ion : QFontMetricsF
            The font metrics of the ion(s) for the given font

        pos_end : QPointF
            The start position of the right line

        pos_right : QPointF
            The end position of the right line

        """
        qp.setPen(self._getPen(self.colors["red"]))
        suffix_ions = sorted(self.suffix[index_reverse], reverse=True)
        blank_ion: int = 5

        for ion in suffix_ions:
            height_ion: float = metrics_ion.boundingRect(ion).height()
            pos_ion = QPointF(pos_end.x() + 2.5, pos_right.y() - blank_ion)
            qp.drawText(pos_ion, ion)
            blank_ion += height_ion
    def _drawPrefixIon(self, qp: QPainter, index: int,
                       metrics_ion: QFontMetricsF, pos_left: QPointF) -> None:
        """
        Draws existing prefix ion(s) and the left line at this position.

        Parameters
        ----------
        qp : QPainter
            The QPainter class provides functions required to paint within the
            widget

        index: int
            The position of the prefix ion(s) within the peptide

        metrics_ion : QFontMetricsF
            The font metrics of the ion(s) for the given font

        pos_left : QPointF
            The coordination of the left line provided for the prefix ion(s)

        """
        qp.setPen(self._getPen(self.colors["blue"]))
        prefix_ions = sorted(self.prefix[index])
        blank_ion: int = 10

        for ion in prefix_ions:
            height_ion: float = metrics_ion.boundingRect(ion).height()
            pos_ion = QPointF(pos_left.x(), pos_left.y() + blank_ion)
            qp.drawText(pos_ion, ion)
            blank_ion += height_ion
Exemple #4
0
    def reposition(self):

        fm = QFontMetricsF(self._font, self)
        rect = fm.boundingRect(QRectF(self.rect()), Qt.AlignCenter,
                               str(self._value))
        self._xpos = -rect.width() / 2.0
        self._ypos = rect.height() / 2.0 - fm.descent()
        self.update()
Exemple #5
0
    def rescale(self):

        fm = QFontMetricsF(self._font, self)
        maxRect = fm.boundingRect(QRectF(self.rect()), Qt.AlignCenter,
                                  str(self._maximum))
        xscale = float(self.width()) / maxRect.width()
        yscale = float(self.height()) / maxRect.height()
        self._scale = min(xscale, yscale)
Exemple #6
0
    def reposition(self):

        fm = QFontMetricsF(self._font, self)
        rect = fm.boundingRect(QRectF(self.rect()), Qt.AlignCenter,
                str(self._value))
        self._xpos = -rect.width()/2.0
        self._ypos = rect.height()/2.0 - fm.descent()
        self.update()
Exemple #7
0
    def rescale(self):

        fm = QFontMetricsF(self._font, self)
        maxRect = fm.boundingRect(QRectF(self.rect()), Qt.AlignCenter,
                str(self._maximum))
        xscale = float(self.width())/maxRect.width()
        yscale = float(self.height())/maxRect.height()
        self._scale = min(xscale, yscale)
Exemple #8
0
 def __outline_rect(self):
     """:rtype QRectF"""
     padding = 8
     metrics = QFontMetricsF()
     rect = metrics.boundingRect(self.text)
     """:type rect: QRectF"""
     rect.adjust(-padding, -padding, padding, padding)
     rect.translate(-rect.center())
     return rect
Exemple #9
0
 def _drawGridDivs_x(self, painter: QPainter, step: float):
     """отрисовка значений делений на оси X"""
     if len(self._charts) > 0:
         logger.debug(self._drawGridDivs_x.__doc__)
         axis: Axis = self._charts[self._base_chart].getAxis('x')
         fm = QFontMetricsF(self._style['grid']['font'])
         for i, div in axis.generateDivSteps():
             text = str(round(div, 8))
             offset_x = self._margins[0] - fm.boundingRect(text).width() / 2.0
             offset_y = self.height() - self._margins[3] + fm.height() + 5
             painter.drawText(QPointF(offset_x + i * step,
                                      offset_y),
                              text)
Exemple #10
0
 def _drawGridDivs_x(self, painter: QPainter, step: float):
     """отрисовка значений делений на оси X"""
     if not self._grid_divs['x0'].is_ready:
         return
     # logger.debug(self._drawGridDivs_x.__doc__)
     f_m = QFontMetricsF(self._style['grid']['font'])
     divs = self._grid_divs['x0'].divs
     pen = painter.pen()
     painter.setPen(self._style['grid']['border'])
     for i, div in enumerate(divs):
         text = str(div)
         offset_x = self._margins[0] - f_m.boundingRect(text).width() / 2.0
         offset_y = self.height() - self._margins[3] + f_m.height() + 5
         painter.drawText(QPointF(offset_x + i * step, offset_y), text)
     painter.setPen(pen)
    def _draw_volume_axes(self, painter):
        painter.save()

        metrics = QFontMetricsF(painter.font())

        scale_factor = decompose_matrix(self._model)[0]

        pen = QPen()
        origin = self._project([0] * 3)
        for i in range(3):
            pt = [0] * 3
            pt[i] = 1

            # axis line
            color = [0] * 3
            color[i] = 255

            pen.setColor(QColor(*color))
            painter.setPen(pen)
            brush = QBrush(QColor(*color), Qt.SolidPattern)
            painter.setBrush(brush)

            pt = self._project(pt)
            painter.drawLine(QPointF(*origin), QPointF(*pt))
            circle = QRectF(-1.5, -1.5, 3, 3)
            circle.translate(*pt)
            painter.drawEllipse(circle)

            # axis label
            pen.setColor(QColor(255, 255, 255))
            painter.setPen(pen)

            text = f'{self._state.cropped_shape_mm[::-1][i]:.2f} mm\n{self._state.cropped_shape_vx[::-1][i]} vx'
            if abs(scale_factor[::-1][i] - 1) > 1e-2:
                text += f'\n({scale_factor[::-1][i]:.2f}x)'

            bounds = metrics.boundingRect(QRectF(-100, -100, 200, 200),
                                          Qt.AlignCenter, text)

            eps = 1e-6
            norm = (pt - origin) / (numpy.linalg.norm(pt - origin) + eps)
            shift = numpy.abs([bounds.width(), bounds.height()] /
                              (norm + eps) / 2)
            bounds.translate(*(pt + (min(shift) + 5) * norm))

            painter.drawText(bounds, Qt.AlignCenter, text)

        painter.restore()
 def syncWithMapObject(self, renderer):
     nameVisible = self.mObject.isVisible() and self.mObject.name()!=''
     self.setVisible(nameVisible)
     if (not nameVisible):
         return
     metrics = QFontMetricsF(QGuiApplication.font())
     boundingRect = metrics.boundingRect(self.mObject.name())
     boundingRect.translate(-boundingRect.width() / 2, -labelDistance)
     boundingRect.adjust(-labelMargin*2, -labelMargin, labelMargin*2, labelMargin)
     pixelPos = renderer.pixelToScreenCoords_(self.mObject.position())
     bounds = objectBounds(self.mObject, renderer)
     # Adjust the bounding box for object rotation
     transform = QTransform()
     transform.translate(pixelPos.x(), pixelPos.y())
     transform.rotate(self.mObject.rotation())
     transform.translate(-pixelPos.x(), -pixelPos.y())
     bounds = transform.mapRect(bounds)
     # Center the object name on the object bounding box
     pos = QPointF((bounds.left() + bounds.right()) / 2, bounds.top())
     self.setPos(pos + self.mObject.objectGroup().offset())
     if (self.mBoundingRect != boundingRect):
         self.prepareGeometryChange()
         self.mBoundingRect = boundingRect
 def syncWithMapObject(self, renderer):
     nameVisible = self.mObject.isVisible() and self.mObject.name() != ''
     self.setVisible(nameVisible)
     if (not nameVisible):
         return
     metrics = QFontMetricsF(QGuiApplication.font())
     boundingRect = metrics.boundingRect(self.mObject.name())
     boundingRect.translate(-boundingRect.width() / 2, -labelDistance)
     boundingRect.adjust(-labelMargin * 2, -labelMargin, labelMargin * 2,
                         labelMargin)
     pixelPos = renderer.pixelToScreenCoords_(self.mObject.position())
     bounds = objectBounds(self.mObject, renderer)
     # Adjust the bounding box for object rotation
     transform = QTransform()
     transform.translate(pixelPos.x(), pixelPos.y())
     transform.rotate(self.mObject.rotation())
     transform.translate(-pixelPos.x(), -pixelPos.y())
     bounds = transform.mapRect(bounds)
     # Center the object name on the object bounding box
     pos = QPointF((bounds.left() + bounds.right()) / 2, bounds.top())
     self.setPos(pos + self.mObject.objectGroup().offset())
     if (self.mBoundingRect != boundingRect):
         self.prepareGeometryChange()
         self.mBoundingRect = boundingRect
    def _fragmentPeptide(self, qp: QPainter) -> None:
        """
        The sequence will be generated stepwise by drawing each aa of the
        sequence separately and adding in each step lines and existing ions.

        The procedure can be described in two steps:
        1. Check if sequence is given, if so
        then transform seq into a dictionary
        (with the indices representing the positions of the chars).
        2. For each char in the sequence:
            Firstly, calculate start position of char
            (be aware that the char rect is created
            at the left bottom corner of
            the char, meaning we have to add the height of the Font
            & possible suffixes to the starting height position
            to move it into the center of the window).

            Secondly, calculate the center point for the vertical Line.
            The Line consists of a point start and point end.
            The starting line xPos yield in the
            start_point + blank - (SPACE/2),
            where blank represents the additional
            space from the starting point after each new char.

            Third, if prefix or suffix ions are given,
            then distinguish between suffix and prefix to draw the vertical
            line with either left or right line or both.

            Because of changing the fonts for the ions,
            the fonts needs to be reset.

        Parameters
        ----------
        qp : QPainter
            The QPainter class provides functions required to paint within the
            widget

        """
        blankspace: int = 8

        if self.sequence != "":

            seq = list(self.sequence)
            dict_seq = {i: seq[i] for i in range(0, len(seq))}

            metrics = QFontMetricsF(self.getFont_Pep())

            blank: int = 0
            for i, s in dict_seq.items():
                i_rev = self._getReverseIndex(i, dict_seq)

                width = metrics.boundingRect(s).width()
                height = metrics.boundingRect(s).height()

                start_point = 0

                # position of char with center indent
                position = QPointF(start_point + blank,
                                   SequenceIonsWidget.SUFFIX_HEIGHT + height)
                qp.drawText(position, s)

                # position lines for possible ions
                centerOfLine = \
                    (
                        SequenceIonsWidget.SUFFIX_HEIGHT + height - height / 4
                    ) - 1

                start_linePos = QPointF(start_point + blank - (blankspace / 2),
                                        centerOfLine - height / 2 - 2.5)
                end_linePos = QPointF(start_linePos.x(),
                                      centerOfLine + height / 2 + 2.5)

                qp.setFont(self.getFont_Ion())
                metrics_ion = QFontMetricsF(self.getFont_Ion())

                if i in self.prefix:
                    left_linePos = self._drawIonsLines(qp, start_linePos,
                                                       end_linePos, blankspace,
                                                       "prefix")
                    self._drawPrefixIon(qp, i, metrics_ion, left_linePos)

                # for given line of existing prefix, expand with given suffix
                if i in self.prefix and i_rev in self.suffix:
                    right_linePos = self._drawIonsLines(
                        qp, start_linePos, end_linePos, blankspace, "suffix")
                    self._drawSuffixIon(qp, i_rev, metrics_ion, end_linePos,
                                        right_linePos)

                elif i_rev in self.suffix and i not in self.prefix:
                    right_linePos = self._drawIonsLines(
                        qp, start_linePos, end_linePos, blankspace, "suffix")
                    self._drawSuffixIon(qp, i_rev, metrics_ion, start_linePos,
                                        right_linePos)

                blank += width + blankspace
                qp.setPen(self._getPen(self.colors["black"]))
                qp.setFont(self.getFont_Pep())
    def paintEvent(self, e):
        # ref: https://forums.khronos.org/showthread.php/62124
        # self._projection = perspective(30 * self.height() / 512, self.width() / self.height(), 0.01, 100)
        s = 1 / tan(radians(self._state.projection_fov) / 2)
        self._projection = perspective2(s * 512 / self.height(),
                                        s * 512 / self.width(), 0.01, 100)
        self._viewport = viewport(0, self.height(), self.width(),
                                  -self.height())

        self._crop_corners = list(product(*self._state.volume_crop))
        pts = [self._project(c) for c in self._crop_corners]
        top_left = [
            min([c[i] - self._screen_bounds_padding for c in pts])
            for i in range(2)
        ]
        bottom_right = [
            max([c[i] + self._screen_bounds_padding for c in pts])
            for i in range(2)
        ]

        self._screen_bounds_render = [[
            quantized_floor(x, self._scale_render) for x in top_left
        ], [quantized_ceil(x, self._scale_render) for x in bottom_right]]
        self._screen_bounds_display = [[
            quantized_floor(x, self._scale_display) for x in top_left
        ], [quantized_ceil(x, self._scale_display) for x in bottom_right]]

        self._resolution_render = (
            (numpy.array(self._screen_bounds_render[1]) -
             self._screen_bounds_render[0]) // self._scale_render).astype(
                 numpy.intp)

        painter = QPainter(self)

        # background
        if self._transparency:
            painter.fillRect(self.rect(), Qt.magenta)
        else:
            painter.fillRect(self.rect(), Qt.black)

        # volume
        self._draw_volume(painter)

        # annotations
        if self._annotations > 0:
            painter.setRenderHint(QPainter.Antialiasing)
            painter.setRenderHint(QPainter.TextAntialiasing)

            self._draw_volume_axes(painter)
            self._draw_volume_bounding_box(painter)

            metrics = QFontMetricsF(painter.font())

            pen = QPen()
            pen.setColor(QColor(255, 255, 255))
            painter.setPen(pen)

            dt = numpy.mean(self._render_times or [0])
            self._render_times = self._render_times[-10:]

            lines = [
                (2, f'{self._state.display_volume.renderer.type}  {1e3*dt:6.1f} ms  {1/(dt+1e-6):6.1f} fps'),
                (2, f'{self._resolution_display[0]} \u00d7 {self._resolution_display[1]} px'.ljust(15) \
                    + f'{self._state.display_volume.shape[0]} \u00d7 {self._state.display_volume.shape[1]} \u00d7 {self._state.display_volume.shape[2]} vx'),
                (1, f'{self._state.volume_position+1} of {self._state.volume_count}'),
                (1, f'{self._resolution_render[0]} \u00d7 {self._resolution_render[1]} px'),
                (2, f'{self._state.acquired_shape_mm[0]:.2f} \u00d7 {self._state.acquired_shape_mm[1]:.2f} \u00d7 {self._state.acquired_shape_mm[2]:.2f} mm'),
                (2, f'{self._state.acquired_shape_vx[0]} \u00d7 {self._state.acquired_shape_vx[1]} \u00d7 {self._state.acquired_shape_vx[2]} vx'),
                (1, self._state.filename),
            ]

            i = 0
            for (lvl, line) in reversed(lines):
                if self._annotations >= lvl:
                    painter.drawText(
                        3,
                        self.height() - i * metrics.height() -
                        metrics.descent() - 2, line)
                    i += 1

            scale_factor, _, angles, translation, _ = decompose_matrix(
                self._view * self._model)

            lines = [
                (1,
                 f'{degrees(angles[0]):+6.1f}\u00b0  {degrees(angles[1]):+6.1f}\u00b0  {degrees(angles[2]):+6.1f}\u00b0'
                 ),
            ]

            i = 0
            for (lvl, line) in reversed(lines):
                if self._annotations >= lvl:
                    painter.drawText(
                        self.width() - 3 - metrics.boundingRect(line).width(),
                        self.height() - i * metrics.height() -
                        metrics.descent() - 2, line)
                    i += 1

        if self._annotations >= 2:
            if self._status_text:
                rect = metrics.boundingRect(self._status_text)
                painter.drawText(self.width() - rect.width() - 3,
                                 rect.height(), self._status_text)
Exemple #16
0
    def paintEvent(self, event=None):
        font = QFont(self.font())
        font.setPointSize(font.pointSize() - 1)
        # Returns -1 if the font size was specified in pixels.
        fm = QFontMetricsF(font)
        fracWidth = fm.width(FractionSlider.WSTRING) # 一个字母所占的宽度
        indent = fm.boundingRect("9").width() / 2.0 # 半个字母的宽度
        # Returns the bounding rectangle of the characters in the string specified by text. 
        if not X11:
            fracWidth *= 1.5
        span = self.width() - (FractionSlider.XMARGIN * 2) # 尺子的宽度
        value = self.__numerator / float(self.__denominator) # 当前滑块的值

        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing) # 设置抗锯齿
        painter.setRenderHint(QPainter.TextAntialiasing) # 设置字体抗锯齿
        painter.setPen(self.palette().color(QPalette.Midlight)) # setPen 可以接受Pen、PenStyle、Color对象 这里指的是Color
        # painter.setPen(QColor(220,100,100)) # 这里设置的是QWidght的边框
        painter.setBrush(self.palette().brush(
                QPalette.AlternateBase))
        # setBrush() : Sets the brush for the given color role to the specified brush for all groups in the palette.
        # [Color Role] QPalette.AlternateBase : Used as the alternate background color in views with alternating row colors
        # self.palette() This property holds the widget's palette 其会和默认的调色版混合呈现,但是其一般不能传递到窗口,需要特殊设置,推荐使用CSS 
        painter.drawRect(self.rect())
        segColor = QColor(Qt.gray).lighter(80) # 尺度条颜色:lighter(factor) 150表示50%亮,对于darker(factor) 300表示3倍暗
        segLineColor = segColor.darker() # 默认200 lighter默认 150
        painter.setPen(segLineColor)
        painter.setBrush(segColor)
        painter.drawRect(FractionSlider.XMARGIN,
                         FractionSlider.YMARGIN, span, fm.height())
        textColor = self.palette().color(QPalette.Text)
        segWidth = span / self.__denominator
        segHeight = fm.height() * 2
        nRect = fm.boundingRect(FractionSlider.WSTRING)
        x = FractionSlider.XMARGIN
        yOffset = segHeight + fm.height()
        for i in range(self.__denominator + 1):
            painter.setPen(segLineColor) # 设置线的颜色作为Pen
            painter.drawLine(x, FractionSlider.YMARGIN, x, segHeight) # 划竖线,从(x,ymargin)开始,到(x,segheight)为止。
            painter.setPen(textColor)
            y = segHeight
            rect = QRectF(nRect)
            rect.moveCenter(QPointF(x, y + fm.height() / 2.0))
            #painter.drawText(rect, Qt.AlignCenter,
                             #QString.number(i))
            painter.drawText(rect, Qt.AlignCenter,str(i))            
            y = yOffset
            rect.moveCenter(QPointF(x, y + fm.height() / 2.0))
            painter.drawText(rect, Qt.AlignCenter,
                             str(self.__denominator))
            painter.drawLine(QPointF(rect.left() + indent, y),
                             QPointF(rect.right() - indent, y))
            x += segWidth
        span = int(span)
        y = FractionSlider.YMARGIN - 0.5
        triangle = [QPointF(value * span, y),
                    QPointF((value * span) +
                            (2 * FractionSlider.XMARGIN), y),
                    QPointF((value * span) +
                            FractionSlider.XMARGIN, fm.height())]
        triangledict = (QPointF(value * span, y),
                    QPointF((value * span) +
                            (2 * FractionSlider.XMARGIN), y),
                    QPointF((value * span) +
                            FractionSlider.XMARGIN, fm.height()))
        painter.setPen(QColor(Qt.yellow).darker(100))
        # painter.setBrush(Qt.darkYellow)
        painter.setBrush(QColor(Qt.yellow).darker(200))
        painter.drawPolygon(QPolygonF(triangle))