示例#1
0
    def pointAt(self, axes, axis_values):
        """
        Returns the point that best represents this graph information.
        
        :param      axes        | [<XChartAxis>, ..]
                    axis_values | {<str> axisName, <variant> value
        
        :return     <QPointF>
        """
        point = QPointF()

        rect = self._buildData.get('axis_rect')
        if not rect:
            return point

        x_range = rect.right() - rect.left()
        y_range = rect.bottom() - rect.top()

        for axis in axes:
            if not axis.name() in axis_values:
                continue

            perc = axis.percentAt(axis_values[axis.name()])
            if axis.orientation() == Qt.Vertical:
                point.setY(rect.bottom() - perc * y_range)
            else:
                point.setX(rect.left() + perc * x_range)

        return point
示例#2
0
 def draw(self, qpainter, zoom=1):
     """Draw this figure
     Parameters
     ----------
     qpainter: PySide.QtGui.QPainter
     """
     size_x = self.size_x * zoom
     size_y = self.size_y * zoom
     pensize = 3
     qpainter.setPen(
         QtGui.QPen(PipelineDrawer.blue_cta, pensize, QtCore.Qt.SolidLine))
     text_pos = QPointF(self.center)
     text_pos.setX(text_pos.x() - size_x / 2 + 2)
     text_pos.setY(text_pos.y() + pensize)
     qpainter.drawText(text_pos, str(self.nb_job_done))
     pt = QPointF(self.center)
     pt.setX(5)
     pos = self.name.find("$$thread_number$$")
     if pos != -1:
         name = self.name[0:pos]
     else:
         name = self.name
     qpainter.drawText(pt, name)
     if self.running == True:
         qpainter.setPen(
             QtGui.QPen(PipelineDrawer.mygreen, 3, QtCore.Qt.SolidLine))
     else:
         qpainter.setPen(
             QtGui.QPen(PipelineDrawer.blue_cta, 3, QtCore.Qt.SolidLine))
     x1 = self.center.x() - (size_x / 2)
     y1 = self.center.y() - (size_y / 2)
     qpainter.drawRoundedRect(x1, y1, size_x, size_y, 12.0, 12.0)
示例#3
0
 def pointAt(self, axes, axis_values):
     """
     Returns the point that best represents this graph information.
     
     :param      axes        | [<XChartAxis>, ..]
                 axis_values | {<str> axisName, <variant> value
     
     :return     <QPointF>
     """
     point = QPointF()
     
     rect = self._buildData.get('axis_rect')
     if not rect:
         return point
     
     x_range = rect.right() - rect.left()
     y_range = rect.bottom() - rect.top()
     
     for axis in axes:
         if not axis.name() in axis_values:
             continue
         
         perc = axis.percentAt(axis_values[axis.name()])
         if axis.orientation() == Qt.Vertical:
             point.setY(rect.bottom() - perc * y_range)
         else:
             point.setX(rect.left() + perc * x_range)
     
     return point
示例#4
0
 def showMoveHelper(self, visible=True):
     """show help text In empty HandBoards"""
     if visible:
         if not self.__moveHelper:
             splitter = QGraphicsRectItem(self)
             hbCenter = self.rect().center()
             splitter.setRect(hbCenter.x() * 0.5, hbCenter.y(), hbCenter.x() * 1, 1)
             helpItems = [splitter]
             for name, yFactor in [(m18n('Move Exposed Tiles Here'), 0.5),
                                     (m18n('Move Concealed Tiles Here'), 1.5)]:
                 helper = QGraphicsSimpleTextItem(name, self)
                 helper.setScale(3)
                 nameRect = QRectF()
                 nameRect.setSize(helper.mapToParent(helper.boundingRect()).boundingRect().size())
                 center = QPointF(hbCenter)
                 center.setY(center.y() * yFactor)
                 helper.setPos(center - nameRect.center())
                 if self.sceneRotation() == 180:
                     rotateCenter(helper, 180)
                 helpItems.append(helper)
             self.__moveHelper = self.scene().createItemGroup(helpItems)
         self.__moveHelper.setVisible(True)
     else:
         if self.__moveHelper:
             self.__moveHelper.setVisible(False)
示例#5
0
    def drawPipeline(self, qp):
        """Called by paintEvent, it draws figures and link between them.
        Parameters
        ----------
        qp : QtGui.QPainter
            Performs low-level painting
        """
        # If self.levels is empty, indeed, it does not make sense to draw
        # something.
        if self.levels is None:
            return
        # define Rep position because they change whan resising main windows

        width = self.size().width()
        height = self.size().height()

        if len(self.levels) != 0:
            total_height = (len(self.levels) - 1) * (
                STAGE_SIZE_Y + ROUTER_SIZE_Y)
            self.zoom = height / total_height
        else:
            self.zoom = 1

        #  center figures on screen
        last_point = QPointF(width / 2, -GAP_Y / 2 * self.zoom)
        for level in self.levels:
            total_x = len(level) * STAGE_SIZE_X * self.zoom + (
                len(level) - 1 * STAGE_GAP_X * self.zoom)
            last_point.setX(width / 2 - total_x / 2)
            last_point.setY(last_point.y() + GAP_Y * self.zoom)
            for figure in level:
                figure.setCenter(QPointF(last_point))
                last_point.setX(last_point.x() + STAGE_GAP_X * self.zoom)
        # Start to paint
        size = self.size()
        lines = list()
        last_level_pt = list()
        for level in self.levels:
            current_level_pt = list()
            for figure in level:
                figure.draw(qp, zoom=self.zoom)
                connexion_pt = QPointF(figure.center.x(), figure.center.y()
                                       - figure.size_y / 2 * self.zoom)
                current_level_pt.append(QPointF(connexion_pt.x(),
                                                connexion_pt.y() + figure.size_y * self.zoom))
                # Link to previous level connexion point(s)
                for point in last_level_pt:
                    lines.append(QLineF(point, connexion_pt))
            # Keep points for next level
            last_level_pt = list(current_level_pt)
        for line in lines:
            qp.setPen(QtGui.QPen(self.blue_cta, 1, QtCore.Qt.SolidLine))
            qp.drawLine(line)
示例#6
0
 def draw(self, qpainter, zoom=1):
     """Draw this figure
     Parameters
     ----------
     qpainter: PySide.QtGui.QPainter
     """
     size_x = self.size_x * zoom
     size_y = self.size_y * zoom
     pensize = 3
     qpainter.setPen(
         QtGui.QPen(QtCore.Qt.black, pensize, QtCore.Qt.SolidLine))
     qpainter.drawEllipse(self.center, size_x / 2, size_y / 2)
     text_pos = QPointF(self.center)
     text_pos.setX(text_pos.x() - size_x / 2 + 10)
     text_pos.setY(text_pos.y() + pensize)
     qpainter.drawText(text_pos, str(self.queue_size))
     qpainter.setPen(
         QtGui.QPen(PipelineDrawer.blue_cta, 3, QtCore.Qt.SolidLine))
示例#7
0
    def getXover(self, phg, strandtype, fromHelix,\
                       fromIndex, toHelix, toIndex):
        """
        Draws a line from the center of the fromBase (pA) to the
        top or bottom of that same base, depending on its direction (qA),
        then a quad curve to the top or bottom of the toBase (qB), and
        finally to the center of the toBase (pB).
        """
        # if we need to speed this up, we could keep track if pA changed?
        pA = QPointF(*fromHelix.baseLocation(strandtype,\
                                             fromIndex,\
                                             center=True))
        pA = phg.mapFromItem(fromHelix, pA)
        pB = QPointF(*toHelix.baseLocation(strandtype,\
                                           toIndex,\
                                           center=True))
        pB = phg.mapFromItem(toHelix, pB)
        yA = yB = self._baseWidth / 2
        if fromHelix.vhelix().directionOfStrandIs5to3(strandtype):
            orientA = HandleOrient.LeftUp
            yA = -yA
        else:
            orientA = HandleOrient.RightDown
        if toHelix.vhelix().directionOfStrandIs5to3(strandtype):
            orientB = HandleOrient.RightUp
            yB = -yB
        else:
            orientB = HandleOrient.LeftDown

        # Determine start and end points of quad curve
        qA = QPointF(pA.x(), pA.y() + yA)
        qB = QPointF(pB.x(), pB.y() + yB)

        # Determine control point of quad curve
        c1 = QPointF()
        # case 1: same strand
        if fromHelix.number() == toHelix.number():
            if pA.x() < pB.x():  # draw only from left
                if orientA == HandleOrient.LeftUp or \
                   orientA == HandleOrient.RightUp:
                    dx = abs(pB.x() - pA.x())
                    c1.setX(0.5 * (pA.x() + pB.x()))
                    c1.setY(pA.y() - self.yScale * dx)
                # end if
            # end if
        # case 2: same parity
        elif fromHelix.evenParity() == toHelix.evenParity():
            dy = abs(pB.y() - pA.y())
            c1.setX(pA.x() + self.xScale * dy)
            c1.setY(0.5 * (pA.y() + pB.y()))
        # case 3: default
        else:
            if orientA == HandleOrient.LeftUp:
                c1.setX(pA.x() - self.xScale * abs(pB.y() - pA.y()))
            else:
                c1.setX(pA.x() + self.xScale * abs(pB.y() - pA.y()))
            c1.setY(0.5 * (pA.y() + pB.y()))

        # Construct painter path
        painterpath = QPainterPath()
        painterpath.moveTo(pA)
        painterpath.lineTo(qA)
        painterpath.quadTo(c1, qB)
        painterpath.lineTo(pB)
        return painterpath
示例#8
0
文件: 6.py 项目: wsonv/Wonjun
    def interactiveResize(self, mousePos):
        """
        Perform shape interactive resize.
        """
        offset = self.handleSize + self.handleSpace
        boundingRect = self.boundingRect()
        rect = self.rect()
        diff = QPointF(0, 0)

        self.prepareGeometryChange()

        if self.handleSelected == self.handleTopLeft:

            fromX = self.mousePressRect.left()
            fromY = self.mousePressRect.top()
            toX = fromX + mousePos.x() - self.mousePressPos.x()
            toY = fromY + mousePos.y() - self.mousePressPos.y()
            diff.setX(toX - fromX)
            diff.setY(toY - fromY)
            boundingRect.setLeft(toX)
            boundingRect.setTop(toY)
            rect.setLeft(boundingRect.left() + offset)
            rect.setTop(boundingRect.top() + offset)
            self.setRect(rect)

        elif self.handleSelected == self.handleTopMiddle:

            fromY = self.mousePressRect.top()
            toY = fromY + mousePos.y() - self.mousePressPos.y()
            diff.setY(toY - fromY)
            boundingRect.setTop(toY)
            rect.setTop(boundingRect.top() + offset)
            self.setRect(rect)

        elif self.handleSelected == self.handleTopRight:

            fromX = self.mousePressRect.right()
            fromY = self.mousePressRect.top()
            toX = fromX + mousePos.x() - self.mousePressPos.x()
            toY = fromY + mousePos.y() - self.mousePressPos.y()
            diff.setX(toX - fromX)
            diff.setY(toY - fromY)
            boundingRect.setRight(toX)
            boundingRect.setTop(toY)
            rect.setRight(boundingRect.right() - offset)
            rect.setTop(boundingRect.top() + offset)
            self.setRect(rect)

        elif self.handleSelected == self.handleMiddleLeft:

            fromX = self.mousePressRect.left()
            toX = fromX + mousePos.x() - self.mousePressPos.x()
            diff.setX(toX - fromX)
            boundingRect.setLeft(toX)
            rect.setLeft(boundingRect.left() + offset)
            self.setRect(rect)

        elif self.handleSelected == self.handleMiddleRight:
            print("MR")
            fromX = self.mousePressRect.right()
            toX = fromX + mousePos.x() - self.mousePressPos.x()
            diff.setX(toX - fromX)
            boundingRect.setRight(toX)
            rect.setRight(boundingRect.right() - offset)
            self.setRect(rect)

        elif self.handleSelected == self.handleBottomLeft:

            fromX = self.mousePressRect.left()
            fromY = self.mousePressRect.bottom()
            toX = fromX + mousePos.x() - self.mousePressPos.x()
            toY = fromY + mousePos.y() - self.mousePressPos.y()
            diff.setX(toX - fromX)
            diff.setY(toY - fromY)
            boundingRect.setLeft(toX)
            boundingRect.setBottom(toY)
            rect.setLeft(boundingRect.left() + offset)
            rect.setBottom(boundingRect.bottom() - offset)
            self.setRect(rect)

        elif self.handleSelected == self.handleBottomMiddle:

            fromY = self.mousePressRect.bottom()
            toY = fromY + mousePos.y() - self.mousePressPos.y()
            diff.setY(toY - fromY)
            boundingRect.setBottom(toY)
            rect.setBottom(boundingRect.bottom() - offset)
            self.setRect(rect)

        elif self.handleSelected == self.handleBottomRight:

            fromX = self.mousePressRect.right()
            fromY = self.mousePressRect.bottom()
            toX = fromX + mousePos.x() - self.mousePressPos.x()
            toY = fromY + mousePos.y() - self.mousePressPos.y()
            diff.setX(toX - fromX)
            diff.setY(toY - fromY)
            boundingRect.setRight(toX)
            boundingRect.setBottom(toY)
            rect.setRight(boundingRect.right() - offset)
            rect.setBottom(boundingRect.bottom() - offset)
            self.setRect(rect)

        self.updateHandlesPos()
示例#9
0
class Particle(QGraphicsItem):
    def __init__(self, parent=None):
        super(Particle, self).__init__(parent)
        self.effect = QGraphicsBlurEffect()
        self.blur_radius = random.uniform(0.8, 1.6)
        self.effect.setBlurRadius(self.blur_radius)
        self.setGraphicsEffect(self.effect)
        self.height = random.uniform(1, 6)
        self.width = random.uniform(1, 6)
        self.depth = 1
        self.setZValue(self.depth)
        self.newPos = QPointF()
        self.animation_timer = QTimer()
        self.animation_timer.setInterval(1000 / 25)
        self.animation_timer.timeout.connect(self.advance)
        self.animation_timer.start()
        self.speed = 1
        self.next_pos = QPointF(0, 0)
        self.animated = True
        self.max_speed = 3.0
        self.color = QColor(0, 0, 0, 50)
        # self.change_position_timer = QTimer()
        # self.change_position_timer.setInterval(5000)
        # self.change_position_timer.timeout.connect(self.calculate_next_pos)

    def animate(self, bool):
        self.animated = bool

    def calculate_forces(self):

        # Sum up all forces pushing this item away.
        xvel = 0.0
        yvel = 0.0

        line = QtCore.QLineF(self.next_pos, self.pos())
        dx = line.dx()
        dy = line.dy()
        l = math.sqrt(math.pow(dx, 2) + math.pow(dy, 2))
        # l = 2.0 * (dx * dx + dy * dy)
        if l > 0:
            xvel -= (dx * self.speed) / l
            yvel -= (dy * self.speed) / l
        if l < 10:
            self.calculate_next_pos()

        scene_rect = self.scene().sceneRect()
        self.newPos = self.pos() + QtCore.QPointF(xvel, yvel)
        self.newPos.setX(
            min(max(self.newPos.x(),
                    scene_rect.left() + 10),
                scene_rect.right() - 10))
        self.newPos.setY(
            min(max(self.newPos.y(),
                    scene_rect.top() + 10),
                scene_rect.bottom() - 10))

    def calculate_next_pos(self):
        particle_x = random.uniform(-self.scene().sceneRect().width() / 2,
                                    self.scene().sceneRect().width() / 2)
        particle_y = random.uniform(-self.scene().sceneRect().height() / 2,
                                    self.scene().sceneRect().height() / 2)
        self.next_pos = QPointF(particle_x, particle_y)
        self.blur_radius = random.uniform(0.8, 1.6)
        self.effect.setBlurRadius(self.blur_radius)
        self.setGraphicsEffect(self.effect)
        self.height = random.uniform(1, 6)
        self.width = random.uniform(1, 6)
        self.depth = random.uniform(0, 6)
        self.speed *= random.uniform(0.1, 2.0)
        self.speed %= self.max_speed
        # print self.speed

    def advance(self):
        if self.animated:
            self.calculate_forces()
            if self.newPos == self.pos():
                return False

            self.setPos(self.newPos)
            return True
        else:
            return False

    def paint(self, painter, options, widget=None):
        # painter.drawRect(self.boundingRect())
        painter.setBrush(self.color)
        painter.setPen(self.color)
        painter.drawEllipse(-self.width / 2, -self.height / 2, self.width,
                            self.height)

    def boundingRect(self):
        return QRectF(-self.width / 2, -self.height / 2, self.width,
                      self.height)

    def reduce_speed(self, factor=0.9):
        if factor < 1 and factor > 0:
            self.speed *= factor

    def increase_speed(self, factor=1.1):
        if factor > 1:
            self.speed *= factor

    def set_color(self, color):
        self.color = color

    def instant_pos_change(self):
        particle_x = random.uniform(-self.scene().sceneRect().width() / 2,
                                    self.scene().sceneRect().width() / 2)
        particle_y = random.uniform(-self.scene().sceneRect().height() / 2,
                                    self.scene().sceneRect().height() / 2)
        self.setPos(QPointF(particle_x, particle_y))
        self.next_pos = QPointF(particle_x, particle_y)
示例#10
0
class PixmapDial(QDial):
    # enum CustomPaint
    CUSTOM_PAINT_NULL      = 0
    CUSTOM_PAINT_CARLA_WET = 1
    CUSTOM_PAINT_CARLA_VOL = 2
    CUSTOM_PAINT_CARLA_L   = 3
    CUSTOM_PAINT_CARLA_R   = 4

    # enum Orientation
    HORIZONTAL = 0
    VERTICAL   = 1

    HOVER_MIN = 0
    HOVER_MAX = 9

    def __init__(self, parent):
        QDial.__init__(self, parent)

        self.fPixmap      = QPixmap("./bitmaps/dial_01d.png")
        self.fPixmapNum   = "01"
        self.fCustomPaint = self.CUSTOM_PAINT_NULL

        self.fHovered   = False
        self.fHoverStep = self.HOVER_MIN

        if self.fPixmap.width() > self.fPixmap.height():
            self.fOrientation = self.HORIZONTAL
        else:
            self.fOrientation = self.VERTICAL

        self.fLabel     = ""
        self.fLabelPos  = QPointF(0.0, 0.0)
        self.fLabelFont = QFont()
        self.fLabelFont.setPointSize(6)
        self.fLabelWidth  = 0
        self.fLabelHeight = 0
        self.fLabelGradient = QLinearGradient(0, 0, 0, 1)

        if self.palette().window().color().lightness() > 100:
            # Light background
            c = self.palette().dark().color()
            self.fColor1 = c
            self.fColor2 = QColor(c.red(), c.green(), c.blue(), 0)
            self.fColorT = [self.palette().buttonText().color(), self.palette().mid().color()]
        else:
            # Dark background
            self.fColor1 = QColor(0, 0, 0, 255)
            self.fColor2 = QColor(0, 0, 0, 0)
            self.fColorT = [Qt.white, Qt.darkGray]

        self.updateSizes()

    def getSize(self):
        return self.fSize

    def setCustomPaint(self, paint):
        self.fCustomPaint = paint
        self.fLabelPos.setY(self.fSize + self.fLabelHeight/2)
        self.update()

    def setEnabled(self, enabled):
        if self.isEnabled() != enabled:
            self.fPixmap.load("./bitmaps/dial_%s%s.png" % (self.fPixmapNum, "" if enabled else "d"))
            self.updateSizes()
            self.update()
        QDial.setEnabled(self, enabled)

    def setLabel(self, label):
        self.fLabel = label

        self.fLabelWidth  = QFontMetrics(self.fLabelFont).width(label)
        self.fLabelHeight = QFontMetrics(self.fLabelFont).height()

        self.fLabelPos.setX(float(self.fSize)/2.0 - float(self.fLabelWidth)/2.0)
        self.fLabelPos.setY(self.fSize + self.fLabelHeight)

        self.fLabelGradient.setColorAt(0.0, self.fColor1)
        self.fLabelGradient.setColorAt(0.6, self.fColor1)
        self.fLabelGradient.setColorAt(1.0, self.fColor2)

        self.fLabelGradient.setStart(0, float(self.fSize)/2.0)
        self.fLabelGradient.setFinalStop(0, self.fSize + self.fLabelHeight + 5)

        self.fLabelGradientRect = QRectF(float(self.fSize)/8.0, float(self.fSize)/2.0, float(self.fSize*6)/8.0, self.fSize+self.fLabelHeight+5)
        self.update()

    def setPixmap(self, pixmapId):
        self.fPixmapNum = "%02i" % pixmapId
        self.fPixmap.load("./bitmaps/dial_%s%s.png" % (self.fPixmapNum, "" if self.isEnabled() else "d"))

        if self.fPixmap.width() > self.fPixmap.height():
            self.fOrientation = self.HORIZONTAL
        else:
            self.fOrientation = self.VERTICAL

        self.updateSizes()
        self.update()

    def minimumSizeHint(self):
        return QSize(self.fSize, self.fSize)

    def sizeHint(self):
        return QSize(self.fSize, self.fSize)

    def updateSizes(self):
        self.fWidth  = self.fPixmap.width()
        self.fHeight = self.fPixmap.height()

        if self.fWidth < 1:
            self.fWidth = 1

        if self.fHeight < 1:
            self.fHeight = 1

        if self.fOrientation == self.HORIZONTAL:
            self.fSize  = self.fHeight
            self.fCount = self.fWidth / self.fHeight
        else:
            self.fSize  = self.fWidth
            self.fCount = self.fHeight / self.fWidth

        self.setMinimumSize(self.fSize, self.fSize + self.fLabelHeight + 5)
        self.setMaximumSize(self.fSize, self.fSize + self.fLabelHeight + 5)

    def enterEvent(self, event):
        self.fHovered = True
        if self.fHoverStep == self.HOVER_MIN:
            self.fHoverStep = self.HOVER_MIN + 1
        QDial.enterEvent(self, event)

    def leaveEvent(self, event):
        self.fHovered = False
        if self.fHoverStep == self.HOVER_MAX:
            self.fHoverStep = self.HOVER_MAX - 1
        QDial.leaveEvent(self, event)

    def paintEvent(self, event):
        event.accept()

        painter = QPainter(self)
        painter.save()
        painter.setRenderHint(QPainter.Antialiasing, True)

        if self.fLabel:
            if self.fCustomPaint == self.CUSTOM_PAINT_NULL:
                painter.setPen(self.fColor2)
                painter.setBrush(self.fLabelGradient)
                painter.drawRect(self.fLabelGradientRect)

            painter.setFont(self.fLabelFont)
            painter.setPen(self.fColorT[0 if self.isEnabled() else 1])
            painter.drawText(self.fLabelPos, self.fLabel)

        if self.isEnabled():
            current = float(self.value() - self.minimum())
            divider = float(self.maximum() - self.minimum())

            if divider == 0.0:
                return

            value  = current / divider
            target = QRectF(0.0, 0.0, self.fSize, self.fSize)

            per = int((self.fCount - 1) * value)

            if self.fOrientation == self.HORIZONTAL:
                xpos = self.fSize * per
                ypos = 0.0
            else:
                xpos = 0.0
                ypos = self.fSize * per

            source = QRectF(xpos, ypos, self.fSize, self.fSize)
            painter.drawPixmap(target, self.fPixmap, source)

            # Custom knobs (Dry/Wet and Volume)
            if self.fCustomPaint in (self.CUSTOM_PAINT_CARLA_WET, self.CUSTOM_PAINT_CARLA_VOL):
                # knob color
                colorGreen = QColor(0x5D, 0xE7, 0x3D, 191 + self.fHoverStep*7)
                colorBlue  = QColor(0x3E, 0xB8, 0xBE, 191 + self.fHoverStep*7)

                # draw small circle
                ballRect = QRectF(8.0, 8.0, 15.0, 15.0)
                ballPath = QPainterPath()
                ballPath.addEllipse(ballRect)
                #painter.drawRect(ballRect)
                tmpValue  = (0.375 + 0.75*value)
                ballValue = tmpValue - floor(tmpValue)
                ballPoint = ballPath.pointAtPercent(ballValue)

                # draw arc
                startAngle = 216*16
                spanAngle  = -252*16*value

                if self.fCustomPaint == self.CUSTOM_PAINT_CARLA_WET:
                    painter.setBrush(colorBlue)
                    painter.setPen(QPen(colorBlue, 0))
                    painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.2, 2.2))

                    gradient = QConicalGradient(15.5, 15.5, -45)
                    gradient.setColorAt(0.0,   colorBlue)
                    gradient.setColorAt(0.125, colorBlue)
                    gradient.setColorAt(0.625, colorGreen)
                    gradient.setColorAt(0.75,  colorGreen)
                    gradient.setColorAt(0.76,  colorGreen)
                    gradient.setColorAt(1.0,   colorGreen)
                    painter.setBrush(gradient)
                    painter.setPen(QPen(gradient, 3))

                else:
                    painter.setBrush(colorBlue)
                    painter.setPen(QPen(colorBlue, 0))
                    painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.2, 2.2))

                    painter.setBrush(colorBlue)
                    painter.setPen(QPen(colorBlue, 3))

                painter.drawArc(4.0, 4.0, 26.0, 26.0, startAngle, spanAngle)

            # Custom knobs (L and R)
            elif self.fCustomPaint in (self.CUSTOM_PAINT_CARLA_L, self.CUSTOM_PAINT_CARLA_R):
                # knob color
                color = QColor(0xAD + self.fHoverStep*5, 0xD5 + self.fHoverStep*4, 0x4B + self.fHoverStep*5)

                # draw small circle
                ballRect = QRectF(7.0, 8.0, 11.0, 12.0)
                ballPath = QPainterPath()
                ballPath.addEllipse(ballRect)
                #painter.drawRect(ballRect)
                tmpValue  = (0.375 + 0.75*value)
                ballValue = tmpValue - floor(tmpValue)
                ballPoint = ballPath.pointAtPercent(ballValue)

                painter.setBrush(color)
                painter.setPen(QPen(color, 0))
                painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.0, 2.0))

                # draw arc
                if self.fCustomPaint == self.CUSTOM_PAINT_CARLA_L:
                    startAngle = 216*16
                    spanAngle  = -252.0*16*value
                elif self.fCustomPaint == self.CUSTOM_PAINT_CARLA_R:
                    startAngle = 324.0*16
                    spanAngle  = 252.0*16*(1.0-value)
                else:
                    return

                painter.setPen(QPen(color, 2))
                painter.drawArc(3.5, 4.5, 22.0, 22.0, startAngle, spanAngle)

            if self.HOVER_MIN < self.fHoverStep < self.HOVER_MAX:
                self.fHoverStep += 1 if self.fHovered else -1
                QTimer.singleShot(20, self, SLOT("update()"))

        else: # isEnabled()
            target = QRectF(0.0, 0.0, self.fSize, self.fSize)
            painter.drawPixmap(target, self.fPixmap, target)

        painter.restore()

    def resizeEvent(self, event):
        self.updateSizes()
        QDial.resizeEvent(self, event)
示例#11
0
    def draw(self, painter, size = None):
        """
        :Arguments:
            painter : QPainter
                Opened painter on which to draw
        """
        bounding_rect = QRectF()
        position = self.position
        transfer_function = self.transfer_function
        font = QFont(self.font)
        text_color = self.text_color
        line_color = self.line_color
        line_thickness = self.line_thickness
        value_range = self.value_range
        if size is None:
            viewport = painter.viewport() # viewport rectangle
            mat, ok = painter.worldMatrix().inverted()
            if not ok:
                raise ValueError("Transformation matrix of painter is singular.")
            viewport = mat.mapRect(viewport)
        else:
            viewport = size
# First, prepare the gradient
        w = viewport.width()
        h = viewport.height()
        #print("Size of viewport: {0}x{1}".format(w, h))
        gr = QLinearGradient()
        nb_values = ceil(w/5.0)
        brush_color = QColor()
        for i in range(int(nb_values)):
            brush_color.setRgbF(*transfer_function.rgba(i/nb_values))
            gr.setColorAt(i/nb_values, brush_color)
# Second, find its position
        metric = QFontMetricsF(font, painter.device())
        font_test = [ str(i)*5 for i in range(10) ]
        lim_width = 0
        lim_height = 0
        for t in font_test:
            rect = metric.boundingRect(t)
            lim_width  = max(lim_width,  rect.width())
            lim_height = max(lim_height, rect.height())
        lim_height *= 3
        length = self.scale_length
        shift_length = (1-length)/2
        width = self.scale_width
        shift_width = self.scale_shift_width
        delta_value = value_range[1]-value_range[0]
        if position == "Top":
            scale_rect = QRectF(shift_length*w, shift_width*h, length*w, width*h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.left(), scale_rect.center().y())
            gr.setFinalStop(scale_rect.right(), scale_rect.center().y())
            start_pos = scale_rect.bottomLeft()
            end_pos = scale_rect.bottomRight()
        elif position == "Right":
            scale_rect = QRectF((1-shift_width-width)*w, shift_length*h, width*w, length*h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.center().x(), scale_rect.bottom())
            gr.setFinalStop(scale_rect.center().x(), scale_rect.top())
            start_pos = scale_rect.bottomLeft()
            end_pos = scale_rect.topLeft()
        elif position == "Bottom":
            scale_rect = QRectF(shift_length*w, (1-shift_width-width)*h, length*w, width*h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.left(), scale_rect.center().y())
            gr.setFinalStop(scale_rect.right(), scale_rect.center().y())
            start_pos = scale_rect.topLeft()
            end_pos = scale_rect.topRight()
        elif position == "Left":
            scale_rect = QRectF(shift_width*w, shift_length*h, width*w, length*h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.center().x(), scale_rect.bottom())
            gr.setFinalStop(scale_rect.center().x(), scale_rect.top())
            start_pos = scale_rect.bottomRight()
            end_pos = scale_rect.topRight()
        else:
            raise ValueError("Invalid scale position: %s" % position)
        shift_pos = (end_pos-start_pos)/delta_value
        if position in ["Left", "Right"]:
            is_vertical = True
            length = scale_rect.height()
        else:
            is_vertical = False
            length = scale_rect.width()
# Get the ticks
        ticks = self.selectValues(length, is_vertical, painter)
        if len(ticks) == 0:
            return
        ticks_str, ticks_extra = self._tick2str(ticks)
# Figure the shifts
        dist_to_bar = self.text_to_bar
        max_width = 0
        max_height = 0
        for t in ticks_str:
            rect = metric.boundingRect(t)
            max_width = max(rect.width(), max_width)
            max_height = max(rect.height(), max_height)
        if position == "Left":
            shift_left = dist_to_bar
            shift_top = None
        elif position == "Right":
            shift_left = -dist_to_bar-max_width
            shift_top = None
        elif position == "Top":
            shift_left = None
            shift_top = dist_to_bar
        else:
            shift_left = None
            shift_top = -dist_to_bar-max_height
        painter.save()
        painter.translate(viewport.topLeft())
        #print("viewport.topLeft() = {0}x{1}".format(viewport.left(), viewport.top()))
        painter.setBrush(gr)
        line_pen = QPen(line_color)
        line_pen.setWidth(line_thickness)
        painter.setPen(line_pen)
        painter.drawRect(scale_rect)
        bounding_rect |= scale_rect
        #print("Scale rect: +{0}+{1}x{2}x{3}".format(scale_rect.left(),
            #scale_rect.top(), scale_rect.width(), scale_rect.height()))
        painter.setFont(font)
        painter.setPen(text_color)
        for ts,t in zip(ticks_str, ticks):
            r = metric.boundingRect(ts)
            pos = start_pos+shift_pos*(t-value_range[0])
            if shift_left is None:
                pos.setX( pos.x() - r.width()/2 )
            else:
                pos.setX( pos.x() + shift_left )
            if shift_top is None:
                pos.setY( pos.y() - r.height()/2)
            else:
                pos.setY( pos.y() + shift_top )
            r.moveTo(pos)
            real_rect = painter.drawText(r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter, ts)
            bounding_rect |= real_rect
        if ticks_extra is not None or self.unit:
            unit = self.unit
            exp_width = width = space_width = 0
            exp_txt = ""
            r = exp_r = unit_r = QRectF()
            exp_font = None
            if ticks_extra is not None:
                exp_txt = u"×10"
                r = metric.boundingRect(exp_txt)
                exp_font = QFont(font)
                exp_size = self.exp_size
                if exp_font.pixelSize() != -1:
                    exp_font.setPixelSize(exp_size*exp_font.pixelSize())
                else:
                    exp_font.setPointSizeF(exp_size*exp_font.pointSizeF())
                exp_metric = QFontMetricsF(exp_font, painter.device())
                exp_r = exp_metric.boundingRect(ticks_extra)
            if unit:
                unit_r = metric.boundingRect(unit)
            total_width = r.width()+exp_r.width()+unit_r.width()
            total_height = max(r.height(),unit_r.height())+exp_r.height()/2
            pos = scale_rect.topRight()
            log_debug("top right of scale bar = (%g,%g)" % (pos.x(), pos.y()))
            log_debug("Size of image = (%d,%d)" % (w,h))
            log_debug("Size of text = (%g,%g)" % (total_width, total_height))
            if position == "Bottom":
                pos.setY(pos.y() + scale_rect.height() + dist_to_bar)
                pos.setX(pos.x() - total_width)
            elif position == "Top":
                pos.setY(pos.y() - dist_to_bar - total_height)
                pos.setX(pos.x() - total_width)
            else: # position == "left" or "right"
                pos.setX(pos.x() - (scale_rect.width() + total_width)/2)
                if pos.x() < 0:
                    pos.setX(dist_to_bar)
                elif pos.x()+total_width+dist_to_bar > w:
                    pos.setX(w - total_width - dist_to_bar)
                pos.setY(pos.y() - dist_to_bar - total_height)
            log_debug("Display unit at position: (%g,%g)" % (pos.x(), pos.y()))

            if ticks_extra is not None:
                r.moveTo(pos)
                real_rect = painter.drawText(r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter, exp_txt)
                bounding_rect |= real_rect
                pos.setX( pos.x() + r.width() )
                pos.setY( pos.y() - metric.ascent()/2 )
                exp_r.moveTo(pos)
                painter.setFont(exp_font)
                real_rect = painter.drawText(exp_r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter, ticks_extra)
                bounding_rect |= real_rect
                pos.setY(pos.y() + metric.ascent()/2)
            if unit:
                pos.setX(pos.x() + space_width + exp_r.width())
                unit_r.moveTo(pos)
                painter.setFont(font)
                real_rect = painter.drawText(unit_r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter, unit)
                bounding_rect |= real_rect
        # Draw the ticks now
        painter.setPen(line_pen)
        tick_size = self.tick_size
        if is_vertical:
            width = scale_rect.width()*tick_size
        else:
            width = scale_rect.height()*tick_size
        pen_width = painter.pen().widthF()
        if pen_width == 0:
            pen_width = 1.0
        for t in ticks:
            pos1 = start_pos + shift_pos*(t-value_range[0])
            pos2 = QPointF(pos1)
            if is_vertical:
                pos1.setX(scale_rect.left() + pen_width)
                pos2.setX(pos1.x() + width - pen_width)
                painter.drawLine(pos1, pos2)
                pos1.setX(scale_rect.right() - pen_width)
                pos2.setX(pos1.x() - width + pen_width)
                painter.drawLine(pos1, pos2)
            else:
                pos1.setY(scale_rect.top() + pen_width)
                pos2.setY(pos1.y() + width - pen_width)
                painter.drawLine(pos1, pos2)
                pos1.setY(scale_rect.bottom() - pen_width)
                pos2.setY(pos1.y() - width + pen_width)
                painter.drawLine(pos1, pos2)
        painter.restore()
        bounding_rect = bounding_rect.adjusted(-pen_width, -pen_width, pen_width, pen_width)
        return bounding_rect
示例#12
0
 def getRectBetweenTwoPoints(self, firstP, secondP, firstCorner=CornerType.UNDEFINED, secondCorner=CornerType.UNDEFINED):
     
     halfthick = 0.5 * self.CONNECTION_THICKNESS * self.zoomFactor() 
     cornerRoundness = halfthick ** 0.5
     offset = 2*halfthick  #* (cornerRoundness + 1) - 1       # -1 prevents one pixel gaps which sometimes appear at corners.
     
     direction = self.getPointToPointDirection(firstP, secondP)
     
     firstOffset = 0
     if self.cornerIsDefined(firstCorner):
         firstOffset = offset
         
     secondOffset = 0
     if self.cornerIsDefined(secondCorner):
         secondOffset = offset
     
     topLeft = QPointF()
     bottomRight = QPointF()
     if direction == self.ConnectionDirection.LEFT:
         # horizontal, negative
         topLeft.setX(secondP.x() + secondOffset)
         topLeft.setY(secondP.y() - halfthick)
         bottomRight.setX(firstP.x() - firstOffset + 1)
         bottomRight.setY(firstP.y() + halfthick)
     elif direction == self.ConnectionDirection.RIGHT:
         # horizontal, positive
         topLeft.setX(firstP.x() + firstOffset)
         topLeft.setY(firstP.y() - halfthick)
         bottomRight.setX(secondP.x() - secondOffset + 1)
         bottomRight.setY(secondP.y() + halfthick)
     elif direction == self.ConnectionDirection.UP:
         # vrtical, negative
         topLeft.setX(secondP.x() - halfthick)
         topLeft.setY(secondP.y() + secondOffset)
         bottomRight.setX(firstP.x() + halfthick)
         bottomRight.setY(firstP.y() - firstOffset + 1)
     elif direction == self.ConnectionDirection.DOWN:
         # vertical, positive
         topLeft.setX(firstP.x() - halfthick)
         topLeft.setY(firstP.y() + firstOffset)
         bottomRight.setX(secondP.x() + halfthick)
         bottomRight.setY(secondP.y() - secondOffset + 1)
     else:
         return QRectF(topLeft, bottomRight)
     
     return QRectF(topLeft, bottomRight)
示例#13
0
 def betweenTwoPoints(self, point, first, second):
     """ Checks whether 'point' lies between 'first' and 'second'.
     
     This function can currently (08-11-15) only deal with horizontal and vertical distances.
     """
     
     halfthick = 0.5 * self.CONNECTION_THICKNESS * self.zoomFactor() 
     direction = self.getPointToPointDirection(first, second)
     
     topLeft = QPointF()
     bottomRight = QPointF()
     if direction == self.ConnectionDirection.LEFT:
         # horizontal, negative
         topLeft.setX(second.x())
         topLeft.setY(second.y() - halfthick)
         bottomRight.setX(first.x())
         bottomRight.setY(first.y() + halfthick)
     elif direction == self.ConnectionDirection.RIGHT:
         # horizontal, positive
         topLeft.setX(first.x())
         topLeft.setY(first.y() - halfthick)
         bottomRight.setX(second.x())
         bottomRight.setY(second.y() + halfthick)
     elif direction == self.ConnectionDirection.UP:
         # vertical, negative
         topLeft.setX(second.x() - halfthick)
         topLeft.setY(second.y())
         bottomRight.setX(first.x() + halfthick)
         bottomRight.setY(first.y())
     elif direction == self.ConnectionDirection.UP:
         # vertical, positive
         topLeft.setX(first.x() - halfthick)
         topLeft.setY(first.y())
         bottomRight.setX(second.x() + halfthick)
         bottomRight.setY(second.y())
     else:
         return False
     
     rect = QRectF(topLeft, bottomRight)
     return rect.contains(QPointF(point))
示例#14
0
class Node(QGraphicsItem):
    Type = QGraphicsItem.UserType + 1

    def __init__(self, graphWidget, text=""):
        super(Node, self).__init__()

        self.graph = graphWidget
        self.edgeList = []
        self.newPos = QPointF()

        self.setFlag(QGraphicsItem.ItemIsMovable)
        self.setFlag(QGraphicsItem.ItemSendsGeometryChanges)
        self.setCacheMode(QGraphicsItem.DeviceCoordinateCache)
        self.setZValue(1)

        self.text = text
        self.active = False

        self.b = 15

    def type(self):
        return Node.Type

    def addEdge(self, edge):
        self.edgeList.append(edge)
        edge.adjust()

    def setActive(self, value=True):
        self.active = value

    def edges(self):
        return self.edgeList

    def calculateForces(self):
        if not self.scene() or self.scene().mouseGrabberItem() is self:
            self.newPos = self.pos()
            return

        # Sum up all forces pushing this item away.
        xvel = 0.0
        yvel = 0.0
        for item in self.scene().items():
            if not isinstance(item, Node):
                continue

            line = QLineF(self.mapFromItem(item, 0, 0), QPointF(0, 0))
            dx = line.dx()
            dy = line.dy()
            l = 2.0 * (dx * dx + dy * dy)
            if l > 0:
                xvel += (dx * 150.0) / l
                yvel += (dy * 150.0) / l

        # Now subtract all forces pulling items together.
        #weight = (len(self.edgeList) + 1) * 100.0
        for edge in self.edgeList:
            if edge.sourceNode() is self:
                pos = self.mapFromItem(edge.destNode(), 0, 0)
            else:
                weight = edge.weight * 6
                pos = self.mapFromItem(edge.sourceNode(), 0, 0)
                xvel += pos.x() / weight
                yvel += pos.y() / weight

        if qAbs(xvel) < 0.1 and qAbs(yvel) < 0.1:
            xvel = yvel = 0.0

        sceneRect = self.scene().sceneRect()
        self.newPos = self.pos() + QPointF(xvel, yvel)
        self.newPos.setX(
            min(max(self.newPos.x(),
                    sceneRect.left() + 10),
                sceneRect.right() - 10))
        self.newPos.setY(
            min(max(self.newPos.y(),
                    sceneRect.top() + 10),
                sceneRect.bottom() - 10))

    def advance(self):
        if self.newPos == self.pos():
            return False

        self.setPos(self.newPos)
        return True

    def boundingRect(self):
        adjust = 2.0
        return QRectF(-self.b - adjust, -self.b - adjust,
                      2 * self.b + 3 + adjust, 2 * self.b + 3 + adjust)

    def shape(self):
        path = QPainterPath()
        path.addEllipse(-self.b, -self.b, 2 * self.b, 2 * self.b)
        return path

    def paint(self, painter, option, widget):
        self.setZValue(5)
        palette = QPalette()

        painter.setPen(Qt.NoPen)
        painter.setBrush(Qt.darkGray)

        gradient = QRadialGradient(-3, -3, 15)
        if option.state & QStyle.State_Sunken or self.active:
            gradient.setCenter(3, 3)
            gradient.setFocalPoint(3, 3)
            gradient.setColorAt(
                1, palette.color(QPalette.Active, QPalette.Button))
            gradient.setColorAt(
                0, palette.color(QPalette.Active, QPalette.Button))
            pen = QPen(palette.color(QPalette.Active, QPalette.ButtonText), 2)
        else:
            gradient.setColorAt(
                1, palette.color(QPalette.Disabled, QPalette.Button))
            gradient.setColorAt(
                0, palette.color(QPalette.Disabled, QPalette.Button))
            pen = QPen(palette.color(QPalette.Disabled, QPalette.ButtonText),
                       0)

        painter.setBrush(QBrush(gradient))
        painter.setPen(pen)
        painter.drawEllipse(-self.b, -self.b, 2 * self.b, 2 * self.b)

        painter.drawText(self.boundingRect(), Qt.AlignCenter, self.text)

    def itemChange(self, change, value):
        if change == QGraphicsItem.ItemPositionHasChanged:
            for edge in self.edgeList:
                edge.adjust()
                self.graph.itemMoved()

        return super(Node, self).itemChange(change, value)

    def mousePressEvent(self, event):
        self.update()
        super(Node, self).mousePressEvent(event)

    def mouseReleaseEvent(self, event):
        self.update()
        super(Node, self).mouseReleaseEvent(event)
示例#15
0
    def betweenTwoPoints(self, point, first, second):
        """ Checks whether 'point' lies between 'first' and 'second'.
        
        This function can currently (08-11-15) only deal with horizontal and vertical distances.
        """

        halfthick = 0.5 * self.CONNECTION_THICKNESS * self.zoomFactor()
        direction = self.getPointToPointDirection(first, second)

        topLeft = QPointF()
        bottomRight = QPointF()
        if direction == self.ConnectionDirection.LEFT:
            # horizontal, negative
            topLeft.setX(second.x())
            topLeft.setY(second.y() - halfthick)
            bottomRight.setX(first.x())
            bottomRight.setY(first.y() + halfthick)
        elif direction == self.ConnectionDirection.RIGHT:
            # horizontal, positive
            topLeft.setX(first.x())
            topLeft.setY(first.y() - halfthick)
            bottomRight.setX(second.x())
            bottomRight.setY(second.y() + halfthick)
        elif direction == self.ConnectionDirection.UP:
            # vertical, negative
            topLeft.setX(second.x() - halfthick)
            topLeft.setY(second.y())
            bottomRight.setX(first.x() + halfthick)
            bottomRight.setY(first.y())
        elif direction == self.ConnectionDirection.UP:
            # vertical, positive
            topLeft.setX(first.x() - halfthick)
            topLeft.setY(first.y())
            bottomRight.setX(second.x() + halfthick)
            bottomRight.setY(second.y())
        else:
            return False

        rect = QRectF(topLeft, bottomRight)
        return rect.contains(QPointF(point))
示例#16
0
class GroundControlPoint():

    def __init__(self, raw=None, map=None, enabled=True):

        self._raw = QPointF()
        self._map = QgsPoint()
        self._local = QPointF()
        self._enabled = True

        self.setRaw(raw)
        self.setMap(map)
        self.setEnabled(enabled)

    def isValid(self):
        return self.isRawSet() and self.isMapSet()

    def isRawSet(self):
        return self._raw is not None

    def raw(self):
        if self._raw is None:
            return QPointF()
        else:
            return self._raw

    def setRaw(self, raw):
        if raw is None:
            self._raw = None
        else:
            self._raw = raw

    def setRawX(self, x):
        if self._raw is None:
            self._raw = QPointF()
        self._raw.setX(x)

    def setRawY(self, y):
        if self._raw is None:
            self._raw = QPointF()
        self._raw.setY(y)

    def isMapSet(self):
        return self._raw is not None

    def map(self):
        if self._map is None:
            return QgsPoint()
        else:
            return self._map

    def setMap(self, map):
        if map is None:
            self._map = None
        else:
            self._map = map

    def local(self):
        if self._local is None:
            return QPointF()
        else:
            return self._local

    def setLocal(self, local):
        if local is None:
            self._local = None
        else:
            self._local = local

    def isEnabled(self):
        return self._enabled

    def setEnabled(self, enabled):
        self._enabled = enabled

    def asCsv(self):
        return utils.csv([self.map().x(), self.map().y(), self.raw().x(), self.raw().y(), int(self._enabled)])
示例#17
0
    def getRectBetweenTwoPoints(self,
                                firstP,
                                secondP,
                                firstCorner=CornerType.UNDEFINED,
                                secondCorner=CornerType.UNDEFINED):

        halfthick = 0.5 * self.CONNECTION_THICKNESS * self.zoomFactor()
        cornerRoundness = halfthick**0.5
        offset = 2 * halfthick  #* (cornerRoundness + 1) - 1       # -1 prevents one pixel gaps which sometimes appear at corners.

        direction = self.getPointToPointDirection(firstP, secondP)

        firstOffset = 0
        if self.cornerIsDefined(firstCorner):
            firstOffset = offset

        secondOffset = 0
        if self.cornerIsDefined(secondCorner):
            secondOffset = offset

        topLeft = QPointF()
        bottomRight = QPointF()
        if direction == self.ConnectionDirection.LEFT:
            # horizontal, negative
            topLeft.setX(secondP.x() + secondOffset)
            topLeft.setY(secondP.y() - halfthick)
            bottomRight.setX(firstP.x() - firstOffset + 1)
            bottomRight.setY(firstP.y() + halfthick)
        elif direction == self.ConnectionDirection.RIGHT:
            # horizontal, positive
            topLeft.setX(firstP.x() + firstOffset)
            topLeft.setY(firstP.y() - halfthick)
            bottomRight.setX(secondP.x() - secondOffset + 1)
            bottomRight.setY(secondP.y() + halfthick)
        elif direction == self.ConnectionDirection.UP:
            # vrtical, negative
            topLeft.setX(secondP.x() - halfthick)
            topLeft.setY(secondP.y() + secondOffset)
            bottomRight.setX(firstP.x() + halfthick)
            bottomRight.setY(firstP.y() - firstOffset + 1)
        elif direction == self.ConnectionDirection.DOWN:
            # vertical, positive
            topLeft.setX(firstP.x() - halfthick)
            topLeft.setY(firstP.y() + firstOffset)
            bottomRight.setX(secondP.x() + halfthick)
            bottomRight.setY(secondP.y() - secondOffset + 1)
        else:
            return QRectF(topLeft, bottomRight)

        return QRectF(topLeft, bottomRight)
示例#18
0
    def draw(self, painter, size=None):
        """
        :Arguments:
            painter : QPainter
                Opened painter on which to draw
        """
        bounding_rect = QRectF()
        position = self.position
        transfer_function = self.transfer_function
        font = QFont(self.font)
        text_color = self.text_color
        line_color = self.line_color
        line_thickness = self.line_thickness
        value_range = self.value_range
        if size is None:
            viewport = painter.viewport()  # viewport rectangle
            mat, ok = painter.worldMatrix().inverted()
            if not ok:
                raise ValueError(
                    "Transformation matrix of painter is singular.")
            viewport = mat.mapRect(viewport)
        else:
            viewport = size
# First, prepare the gradient
        w = viewport.width()
        h = viewport.height()
        #print("Size of viewport: {0}x{1}".format(w, h))
        gr = QLinearGradient()
        nb_values = ceil(w / 5.0)
        brush_color = QColor()
        for i in range(int(nb_values)):
            brush_color.setRgbF(*transfer_function.rgba(i / nb_values))
            gr.setColorAt(i / nb_values, brush_color)
# Second, find its position
        metric = QFontMetricsF(font, painter.device())
        font_test = [str(i) * 5 for i in range(10)]
        lim_width = 0
        lim_height = 0
        for t in font_test:
            rect = metric.boundingRect(t)
            lim_width = max(lim_width, rect.width())
            lim_height = max(lim_height, rect.height())
        lim_height *= 3
        length = self.scale_length
        shift_length = (1 - length) / 2
        width = self.scale_width
        shift_width = self.scale_shift_width
        delta_value = value_range[1] - value_range[0]
        if position == "Top":
            scale_rect = QRectF(shift_length * w, shift_width * h, length * w,
                                width * h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.left(), scale_rect.center().y())
            gr.setFinalStop(scale_rect.right(), scale_rect.center().y())
            start_pos = scale_rect.bottomLeft()
            end_pos = scale_rect.bottomRight()
        elif position == "Right":
            scale_rect = QRectF((1 - shift_width - width) * w,
                                shift_length * h, width * w, length * h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.center().x(), scale_rect.bottom())
            gr.setFinalStop(scale_rect.center().x(), scale_rect.top())
            start_pos = scale_rect.bottomLeft()
            end_pos = scale_rect.topLeft()
        elif position == "Bottom":
            scale_rect = QRectF(shift_length * w,
                                (1 - shift_width - width) * h, length * w,
                                width * h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.left(), scale_rect.center().y())
            gr.setFinalStop(scale_rect.right(), scale_rect.center().y())
            start_pos = scale_rect.topLeft()
            end_pos = scale_rect.topRight()
        elif position == "Left":
            scale_rect = QRectF(shift_width * w, shift_length * h, width * w,
                                length * h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.center().x(), scale_rect.bottom())
            gr.setFinalStop(scale_rect.center().x(), scale_rect.top())
            start_pos = scale_rect.bottomRight()
            end_pos = scale_rect.topRight()
        else:
            raise ValueError("Invalid scale position: %s" % position)
        shift_pos = (end_pos - start_pos) / delta_value
        if position in ["Left", "Right"]:
            is_vertical = True
            length = scale_rect.height()
        else:
            is_vertical = False
            length = scale_rect.width()
# Get the ticks
        ticks = self.selectValues(length, is_vertical, painter)
        if len(ticks) == 0:
            return
        ticks_str, ticks_extra = self._tick2str(ticks)
        # Figure the shifts
        dist_to_bar = self.text_to_bar
        max_width = 0
        max_height = 0
        for t in ticks_str:
            rect = metric.boundingRect(t)
            max_width = max(rect.width(), max_width)
            max_height = max(rect.height(), max_height)
        if position == "Left":
            shift_left = dist_to_bar
            shift_top = None
        elif position == "Right":
            shift_left = -dist_to_bar - max_width
            shift_top = None
        elif position == "Top":
            shift_left = None
            shift_top = dist_to_bar
        else:
            shift_left = None
            shift_top = -dist_to_bar - max_height
        painter.save()
        painter.translate(viewport.topLeft())
        #print("viewport.topLeft() = {0}x{1}".format(viewport.left(), viewport.top()))
        painter.setBrush(gr)
        line_pen = QPen(line_color)
        line_pen.setWidth(line_thickness)
        painter.setPen(line_pen)
        painter.drawRect(scale_rect)
        bounding_rect |= scale_rect
        #print("Scale rect: +{0}+{1}x{2}x{3}".format(scale_rect.left(),
        #scale_rect.top(), scale_rect.width(), scale_rect.height()))
        painter.setFont(font)
        painter.setPen(text_color)
        for ts, t in zip(ticks_str, ticks):
            r = metric.boundingRect(ts)
            pos = start_pos + shift_pos * (t - value_range[0])
            if shift_left is None:
                pos.setX(pos.x() - r.width() / 2)
            else:
                pos.setX(pos.x() + shift_left)
            if shift_top is None:
                pos.setY(pos.y() - r.height() / 2)
            else:
                pos.setY(pos.y() + shift_top)
            r.moveTo(pos)
            real_rect = painter.drawText(
                r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter, ts)
            bounding_rect |= real_rect
        if ticks_extra is not None or self.unit:
            unit = self.unit
            exp_width = width = space_width = 0
            exp_txt = ""
            r = exp_r = unit_r = QRectF()
            exp_font = None
            if ticks_extra is not None:
                exp_txt = u"×10"
                r = metric.boundingRect(exp_txt)
                exp_font = QFont(font)
                exp_size = self.exp_size
                if exp_font.pixelSize() != -1:
                    exp_font.setPixelSize(exp_size * exp_font.pixelSize())
                else:
                    exp_font.setPointSizeF(exp_size * exp_font.pointSizeF())
                exp_metric = QFontMetricsF(exp_font, painter.device())
                exp_r = exp_metric.boundingRect(ticks_extra)
            if unit:
                unit_r = metric.boundingRect(unit)
            total_width = r.width() + exp_r.width() + unit_r.width()
            total_height = max(r.height(),
                               unit_r.height()) + exp_r.height() / 2
            pos = scale_rect.topRight()
            log_debug("top right of scale bar = (%g,%g)" % (pos.x(), pos.y()))
            log_debug("Size of image = (%d,%d)" % (w, h))
            log_debug("Size of text = (%g,%g)" % (total_width, total_height))
            if position == "Bottom":
                pos.setY(pos.y() + scale_rect.height() + dist_to_bar)
                pos.setX(pos.x() - total_width)
            elif position == "Top":
                pos.setY(pos.y() - dist_to_bar - total_height)
                pos.setX(pos.x() - total_width)
            else:  # position == "left" or "right"
                pos.setX(pos.x() - (scale_rect.width() + total_width) / 2)
                if pos.x() < 0:
                    pos.setX(dist_to_bar)
                elif pos.x() + total_width + dist_to_bar > w:
                    pos.setX(w - total_width - dist_to_bar)
                pos.setY(pos.y() - dist_to_bar - total_height)
            log_debug("Display unit at position: (%g,%g)" % (pos.x(), pos.y()))

            if ticks_extra is not None:
                r.moveTo(pos)
                real_rect = painter.drawText(
                    r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter,
                    exp_txt)
                bounding_rect |= real_rect
                pos.setX(pos.x() + r.width())
                pos.setY(pos.y() - metric.ascent() / 2)
                exp_r.moveTo(pos)
                painter.setFont(exp_font)
                real_rect = painter.drawText(
                    exp_r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter,
                    ticks_extra)
                bounding_rect |= real_rect
                pos.setY(pos.y() + metric.ascent() / 2)
            if unit:
                pos.setX(pos.x() + space_width + exp_r.width())
                unit_r.moveTo(pos)
                painter.setFont(font)
                real_rect = painter.drawText(
                    unit_r,
                    Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter, unit)
                bounding_rect |= real_rect
        # Draw the ticks now
        painter.setPen(line_pen)
        tick_size = self.tick_size
        if is_vertical:
            width = scale_rect.width() * tick_size
        else:
            width = scale_rect.height() * tick_size
        pen_width = painter.pen().widthF()
        if pen_width == 0:
            pen_width = 1.0
        for t in ticks:
            pos1 = start_pos + shift_pos * (t - value_range[0])
            pos2 = QPointF(pos1)
            if is_vertical:
                pos1.setX(scale_rect.left() + pen_width)
                pos2.setX(pos1.x() + width - pen_width)
                painter.drawLine(pos1, pos2)
                pos1.setX(scale_rect.right() - pen_width)
                pos2.setX(pos1.x() - width + pen_width)
                painter.drawLine(pos1, pos2)
            else:
                pos1.setY(scale_rect.top() + pen_width)
                pos2.setY(pos1.y() + width - pen_width)
                painter.drawLine(pos1, pos2)
                pos1.setY(scale_rect.bottom() - pen_width)
                pos2.setY(pos1.y() - width + pen_width)
                painter.drawLine(pos1, pos2)
        painter.restore()
        bounding_rect = bounding_rect.adjusted(-pen_width, -pen_width,
                                               pen_width, pen_width)
        return bounding_rect
示例#19
0
class PixmapDial(QDial):
    HORIZONTAL = 0
    VERTICAL   = 1

    CUSTOM_PAINT_CARLA_WET = 1
    CUSTOM_PAINT_CARLA_VOL = 2
    CUSTOM_PAINT_CARLA_L   = 3
    CUSTOM_PAINT_CARLA_R   = 4

    HOVER_MIN = 0
    HOVER_MAX = 9

    def __init__(self, parent):
        QDial.__init__(self, parent)

        self.m_pixmap = QPixmap(":/bitmaps/dial_01d.png")
        self.m_pixmap_n_str = "01"
        self.m_custom_paint = 0

        self.m_hovered    = False
        self.m_hover_step = self.HOVER_MIN

        if self.m_pixmap.width() > self.m_pixmap.height():
            self.m_orientation = self.HORIZONTAL
        else:
            self.m_orientation = self.VERTICAL

        self.m_label = ""
        self.m_label_pos = QPointF(0.0, 0.0)
        self.m_label_width = 0
        self.m_label_height = 0
        self.m_label_gradient = QLinearGradient(0, 0, 0, 1)

        if self.palette().window().color().lightness() > 100:
            # Light background
            self.m_color1 = QColor(100, 100, 100, 255)
            self.m_color2 = QColor(0, 0, 0, 0)
            self.m_colorT = [self.palette().text().color(), self.palette().mid().color()]
        else:
            # Dark background
            self.m_color1 = QColor(0, 0, 0, 255)
            self.m_color2 = QColor(0, 0, 0, 0)
            self.m_colorT = [Qt.white, Qt.darkGray]

        self.updateSizes()

    def getSize(self):
        return self.p_size

    def setCustomPaint(self, paint):
        self.m_custom_paint = paint
        self.update()

    def setEnabled(self, enabled):
        if self.isEnabled() != enabled:
            self.m_pixmap.load(":/bitmaps/dial_%s%s.png" % (self.m_pixmap_n_str, "" if enabled else "d"))
            self.updateSizes()
            self.update()
        QDial.setEnabled(self, enabled)

    def setLabel(self, label):
        self.m_label = label

        self.m_label_width  = QFontMetrics(self.font()).width(label)
        self.m_label_height = QFontMetrics(self.font()).height()

        self.m_label_pos.setX((self.p_size / 2) - (self.m_label_width / 2))
        self.m_label_pos.setY(self.p_size + self.m_label_height)

        self.m_label_gradient.setColorAt(0.0, self.m_color1)
        self.m_label_gradient.setColorAt(0.6, self.m_color1)
        self.m_label_gradient.setColorAt(1.0, self.m_color2)

        self.m_label_gradient.setStart(0, self.p_size / 2)
        self.m_label_gradient.setFinalStop(0, self.p_size + self.m_label_height + 5)

        self.m_label_gradient_rect = QRectF(self.p_size * 1 / 8, self.p_size / 2, self.p_size * 6 / 8, self.p_size + self.m_label_height + 5)
        self.update()

    def setPixmap(self, pixmap_id):
        if pixmap_id > 10:
            self.m_pixmap_n_str = str(pixmap_id)
        else:
            self.m_pixmap_n_str = "0%i" % pixmap_id

        self.m_pixmap.load(":/bitmaps/dial_%s%s.png" % (self.m_pixmap_n_str, "" if self.isEnabled() else "d"))

        if self.m_pixmap.width() > self.m_pixmap.height():
            self.m_orientation = self.HORIZONTAL
        else:
            self.m_orientation = self.VERTICAL

        self.updateSizes()
        self.update()

    def minimumSizeHint(self):
        return QSize(self.p_size, self.p_size)

    def sizeHint(self):
        return QSize(self.p_size, self.p_size)

    def updateSizes(self):
        self.p_width = self.m_pixmap.width()
        self.p_height = self.m_pixmap.height()

        if self.p_width < 1:
            self.p_width = 1

        if self.p_height < 1:
            self.p_height = 1

        if self.m_orientation == self.HORIZONTAL:
            self.p_size = self.p_height
            self.p_count = self.p_width / self.p_height
        else:
            self.p_size = self.p_width
            self.p_count = self.p_height / self.p_width

        self.setMinimumSize(self.p_size, self.p_size + self.m_label_height + 5)
        self.setMaximumSize(self.p_size, self.p_size + self.m_label_height + 5)

    def enterEvent(self, event):
        self.m_hovered = True
        if self.m_hover_step == self.HOVER_MIN:
            self.m_hover_step = self.HOVER_MIN + 1
        QDial.enterEvent(self, event)

    def leaveEvent(self, event):
        self.m_hovered = False
        if self.m_hover_step == self.HOVER_MAX:
            self.m_hover_step = self.HOVER_MAX - 1
        QDial.leaveEvent(self, event)

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing, True)

        if self.m_label:
            painter.setPen(self.m_color2)
            painter.setBrush(self.m_label_gradient)
            painter.drawRect(self.m_label_gradient_rect)

            painter.setPen(self.m_colorT[0] if self.isEnabled() else self.m_colorT[1])
            painter.drawText(self.m_label_pos, self.m_label)

        if self.isEnabled():
            current = float(self.value() - self.minimum())
            divider = float(self.maximum() - self.minimum())

            if divider == 0.0:
                return

            target = QRectF(0.0, 0.0, self.p_size, self.p_size)
            value  = (current / divider)

            ## Regular knobs
            #else:
            per = int((self.p_count - 1) * (current / divider))

            if self.m_orientation == self.HORIZONTAL:
                xpos = self.p_size * per
                ypos = 0.0
            else:
                xpos = 0.0
                ypos = self.p_size * per

            source = QRectF(xpos, ypos, self.p_size, self.p_size)
            painter.drawPixmap(target, self.m_pixmap, source)

            # Custom knobs (Dry/Wet and Volume)
            if self.m_custom_paint in (self.CUSTOM_PAINT_CARLA_WET, self.CUSTOM_PAINT_CARLA_VOL):
                # knob color
                colorGreen = QColor(0x5D, 0xE7, 0x3D, 191 + self.m_hover_step*7)
                colorBlue  = QColor(0x3E, 0xB8, 0xBE, 191 + self.m_hover_step*7)

                #colorGreen = QColor(0x5D + self.m_hover_step*6, 0xE7 + self.m_hover_step*1, 0x3D + self.m_hover_step*5)
                #colorBlue  = QColor(0x52 + self.m_hover_step*8, 0xEE + self.m_hover_step*1, 0xF8 + self.m_hover_step/2)

                # draw small circle
                ballPath = QPainterPath()
                ballRect = QRectF(8.0, 8.0, 15.0, 15.0)
                ballPath.addEllipse(ballRect)
                #painter.drawRect(ballRect)
                ballValue = (0.375 + 0.75*value) % 1.0
                ballPoint = ballPath.pointAtPercent(ballValue)

                # draw arc
                startAngle = 216*16
                spanAngle  = -252.0*16*value

                if self.m_custom_paint == self.CUSTOM_PAINT_CARLA_WET:
                    painter.setBrush(colorBlue)
                    painter.setPen(QPen(colorBlue, 0))
                    painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.2, 2.2))

                    gradient = QConicalGradient(15.5, 15.5, -45)
                    gradient.setColorAt(0.0,   colorBlue)
                    gradient.setColorAt(0.125, colorBlue)
                    gradient.setColorAt(0.625, colorGreen)
                    gradient.setColorAt(0.75,  colorGreen)
                    gradient.setColorAt(0.76,  colorGreen)
                    gradient.setColorAt(1.0,   colorGreen)
                    painter.setBrush(gradient)
                    painter.setPen(QPen(gradient, 3))

                else:
                    painter.setBrush(colorBlue)
                    painter.setPen(QPen(colorBlue, 0))
                    painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.2, 2.2))

                    painter.setBrush(colorBlue)
                    painter.setPen(QPen(colorBlue, 3))

                painter.drawArc(4.0, 4.0, 26.0, 26.0, startAngle, spanAngle)

            # Custom knobs (L and R)
            elif self.m_custom_paint in (self.CUSTOM_PAINT_CARLA_L, self.CUSTOM_PAINT_CARLA_R):
                # knob color
                color = QColor(0xAD + self.m_hover_step*5, 0xD5 + self.m_hover_step*4, 0x4B + self.m_hover_step*5)

                # draw small circle
                ballPath = QPainterPath()
                ballRect = QRectF(7.0, 8.0, 11.0, 12.0)
                ballPath.addEllipse(ballRect)
                #painter.drawRect(ballRect)
                ballValue = (0.375 + 0.75*value) % 1.0
                ballPoint = ballPath.pointAtPercent(ballValue)

                painter.setBrush(color)
                painter.setPen(QPen(color, 0))
                painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.0, 2.0))

                # draw arc
                if self.m_custom_paint == self.CUSTOM_PAINT_CARLA_L:
                    startAngle = 216*16
                    spanAngle  = -252.0*16*value
                elif self.m_custom_paint == self.CUSTOM_PAINT_CARLA_R:
                    startAngle = 324.0*16
                    spanAngle  = 252.0*16*(1.0-value)
                else:
                    return

                painter.setPen(QPen(color, 2))
                painter.drawArc(3.5, 4.5, 22.0, 22.0, startAngle, spanAngle)

            if self.HOVER_MIN < self.m_hover_step < self.HOVER_MAX:
                self.m_hover_step += 1 if self.m_hovered else -1
                QTimer.singleShot(20, self, SLOT("update()"))

        elif not self.m_custom_paint:
            target = QRectF(0.0, 0.0, self.p_size, self.p_size)
            source = target
            painter.drawPixmap(target, self.m_pixmap, source)

    def resizeEvent(self, event):
        self.updateSizes()
        QDial.resizeEvent(self, event)