Beispiel #1
0
    def drawValue(self, p, baseRect, value, arcLength):
        # nothing to draw
        if value == self.min:
            return

        # for Line style
        if self.barStyle == self.StyleLine:
            p.setPen(
                QPen(self.palette().highlight().color(), self.dataPenWidth))
            p.setBrush(Qt.NoBrush)
            p.drawArc(
                baseRect.adjusted(self.outlinePenWidth / 2,
                                  self.outlinePenWidth / 2,
                                  -self.outlinePenWidth / 2,
                                  -self.outlinePenWidth / 2),
                self.nullPosition * 16, -arcLength * 16)
            return

        # for Pie and Donut styles
        dataPath = QPainterPath()
        dataPath.setFillRule(Qt.WindingFill)

        # pie segment outer
        dataPath.moveTo(baseRect.center())
        dataPath.arcTo(baseRect, self.nullPosition, -arcLength)
        dataPath.lineTo(baseRect.center())

        p.setBrush(self.palette().highlight())
        p.setBrush(QColor(255, 255, 255, 255 * 0.3))

        # pen = QtGui.QPen(self.palette().shadow().color(), self.dataPenWidth)
        pen = QPen(self.palette().shadow().color(), -1)
        p.setPen(pen)
        p.drawPath(dataPath)
Beispiel #2
0
    def drawArc(self, painter, line):
        topLeftPoint = self.calculatePerpendicularPoint(
            self.fromPoint, 50, line)
        arcRect = QRectF(topLeftPoint, QSizeF(line.length(), 100))
        if self._fromNode is self._toNode:
            spanAngle = -360
        else:
            spanAngle = -180

        path = QPainterPath()
        path.arcMoveTo(arcRect, spanAngle)
        path.arcTo(arcRect, -180, spanAngle)
        painter.drawPath(path)
Beispiel #3
0
class wheel(QWidget):
    currentColorChanged = Signal(QColor)

    def __init__(self, parent=None):
        super(wheel, self).__init__(parent)
        self.setFixedSize(256, 256)

        # start, end angles for value arc
        self.s_ang, self.e_ang = 135, 225

        # offset angle and direction for color wheel
        self.o_ang, self.rot_d = 45, -1  # 1 for clock-wise, -1 for widdershins

        # other initializations
        self.pos = QPointF(-100, -100)
        self.vIdCen = QPointF(-100, -100)
        self.vIdAng = radians(self.s_ang)
        self.chPt = self.pos
        self.hue = self.sat = self.value = 255

        self.setup()
        self.pos = self.cWhBox.center()

        self._namedColorList = []
        self._namedColorPts = []
        self._showNames = False

        self.setMouseTracking(True)
        self.installEventFilter(self)

        self._startedTimer = False


##    def timerSpinner(self):
##        "won't this be fun"
##        self.o_ang -= 1; self.o_ang %= 360
##        stable = False
##
##        colWhl = QConicalGradient(self.cen, self.o_ang)
##        whl_cols = [Qt.red, Qt.magenta,
##                    Qt.blue, Qt.cyan, Qt.green,
##                    Qt.yellow, Qt.red]
##        for i, c in enumerate(whl_cols[::self.rot_d]):
##            colWhl.setColorAt(i / 6.0, c)
##
##        if stable:  # crosshairs stay on color
##            t = radians(self.hue + self.o_ang * -self.rot_d) * -self.rot_d
##            r = self.sat / 255.0 * self.cW_rad
##            x, y = r * cos(t) + self.cen.x(), r * -sin(t) + self.cen.y()
##            self.chPt = QPointF(x, y)
##        else:  # crosshairs stay on point
##            t = atan2(self.cen.y() - self.pos.y(), self.pos.x() - self.cen.x())
##            h = (int(degrees(t)) - self.o_ang) * -self.rot_d
##            self.hue = (h if h > 0 else h + 360) % 360
##            col = QColor(); col.setHsv(self.hue, self.sat, self.value)
##            self.currentColorChanged.emit(col)
##
##        self.cWhlBrush1 = QBrush(colWhl)
##        self.update()

    def resizeEvent(self, event):
        self.setup()  # re-construct the sizes
        self.setNamedColors(self._namedColorList)

    def getColor(self):
        col = QColor()
        col.setHsv(self.hue, self.sat, self.value)
        return col

    def setNamedColors(self, colorList):
        "sets list [(name, #html)] of named colors"
        self._namedColorList = colorList
        lst = []
        r2 = (self.vAoBox.width() + self.vAiBox.width()) / 4.0
        for i in self._namedColorList:
            h, s, v, a = QColor(i[1]).getHsv()

            t = radians(h + self.o_ang * -self.rot_d) * -self.rot_d
            r = s / 255.0 * self.cW_rad
            x, y = r * cos(t) + self.cen.x(), r * -sin(t) + self.cen.y()
            lst.append(QPointF(x, y))

            #t2 = ((v / 255.0) * self.ang_w + radians(self.e_ang) + 2 * pi) % (2 * pi)
            #x, y = r2 * cos(t2) + self.cen.x(), r2 * -sin(t2) + self.cen.y()
            #lst.append(QPointF(x, y))
        self._namedColorPts = lst

    def showNamedColors(self, flag=False):
        "show/hide location of named colors on color wheel"
        self._showNames = flag
        self.update()

    def setColor(self, color):  # saturation -> radius
        h, s, v, a = color.getHsv()  # hue -> angle
        self.hue, self.sat, self.value = h, s, v  # value -> side bar thingy

        t = radians(h + self.o_ang * -self.rot_d) * -self.rot_d
        r = s / 255.0 * self.cW_rad
        x, y = r * cos(t) + self.cen.x(), r * -sin(t) + self.cen.y()
        self.chPt = QPointF(x, y)  # hue, saturation

        self.vIdAng = t2 = (v / 255.0) * self.ang_w + radians(self.e_ang)
        self.vIdAng = t2 = t2 if t2 > 0 else t2 + 2 * pi
        r2 = self.vAoBox.width() / 2.0

        x, y = r2 * cos(t2) + self.cen.x(), r2 * -sin(t2) + self.cen.y()
        self.vIdCen, self.vIdAng = QPointF(x, y), t2  # value
        self.vIdBox.moveCenter(self.vIdCen)
        self.update()

    def eventFilter(self, source, event):
        if (event.type() == QEvent.MouseButtonPress
                or (event.type() == QEvent.MouseMove
                    and event.buttons() == Qt.LeftButton)):
            self.pos = pos = event.pos()

            t = atan2(self.cen.y() - pos.y(), pos.x() - self.cen.x())
            if self.colWhlPath.contains(pos):  # in the color wheel
                self.chPt = pos

                #if not self._startedTimer:
                #    self.timer = QTimer()
                #    self.timer.timeout.connect(self.timerSpinner)
                #    self.timer.start(30.303)
                #    self._startedTimer = True

                # hue -> mouse angle (same as t here)
                h = (int(degrees(t)) - self.o_ang) * -self.rot_d
                self.hue = (h if h > 0 else h + 360) % 360

                # saturation -> mouse radius (clipped to wheel radius)
                m_rad = sqrt((self.pos.x() - self.cen.x())**2 +
                             (self.pos.y() - self.cen.y())**2)
                self.sat = int(255 * min(m_rad / self.cW_rad, 1))

            if self.vInArcPath.contains(pos):  # in the value selection arc
                self.vIdAng = t if t > 0 else t + 2 * pi
                r2 = self.vAoBox.width() / 2.0

                x, y = r2 * cos(t) + self.cen.x(), r2 * -sin(t) + self.cen.y()
                self.vIdCen = QPointF(x, y)
                self.vIdBox.moveCenter(self.vIdCen)
                self.value = int(255 *
                                 (t - radians(self.e_ang)) / self.ang_w) % 256

            self.update()
            col = QColor()
            col.setHsv(self.hue, self.sat, self.value)
            self.currentColorChanged.emit(col)
        return QWidget.eventFilter(self, source, event)

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

        #painter.setBrush(QBrush(Qt.black, Qt.NoBrush))
        #painter.drawRect(self.winBox)  # border

        # value selector indicator
        painter.setBrush(QBrush(Qt.black, Qt.SolidPattern))
        painter.drawPie(self.vIdBox, 16 * (degrees(self.vIdAng) - 22.5), 720)

        # value selector arc
        painter.setClipPath(self.vArcPath)
        painter.setPen(Qt.NoPen)
        arc = QConicalGradient(self.cen, self.e_ang)
        color = QColor()
        color.setHsv(self.hue, self.sat, 255)
        arc.setColorAt(1 - (self.e_ang - self.s_ang) / 360.0, color)
        arc.setColorAt(1, Qt.black)
        arc.setColorAt(0, Qt.black)
        painter.setBrush(arc)
        painter.drawPath(self.vArcPath)
        painter.setClipPath(self.vArcPath, Qt.NoClip)

        # color wheel
        painter.setPen(Qt.NoPen)
        painter.setBrush(self.cWhlBrush1)
        painter.drawEllipse(self.cWhBox)
        painter.setBrush(self.cWhlBrush2)
        painter.drawEllipse(self.cWhBox)

        # crosshairs
        painter.setClipPath(self.colWhlPath)
        painter.setBrush(QBrush(Qt.black, Qt.SolidPattern))
        chVert = QRectF(0, 0, 2, 20)
        chHort = QRectF(0, 0, 20, 2)
        chVert.moveCenter(self.chPt)
        chHort.moveCenter(self.chPt)
        painter.drawRect(chVert)
        painter.drawRect(chHort)

        # named color locations
        if self._showNames:
            painter.setClipPath(self.vArcPath, Qt.NoClip)
            painter.setPen(Qt.SolidLine)
            try:
                painter.drawPoints(*self._namedColorPts)  # PyQt
            except:
                painter.drawPoints(self._namedColorPts)  # PySide

    def setup(self):
        "sets bounds on value arc and color wheel"
        # bounding boxes
        self.winBox = QRectF(self.rect())
        self.vIoBox = QRectF()  # value indicator arc outer
        self.vIdBox = QRectF()  # value indicator box
        self.vAoBox = QRectF()  # value arc outer
        self.vAiBox = QRectF()  # value arc inner
        self.cWhBox = QRectF()  # color wheel

        self.vIdBox.setSize(QSizeF(15, 15))
        self.vIoBox.setSize(self.winBox.size())
        self.vAoBox.setSize(self.winBox.size() - self.vIdBox.size() / 2.0)
        self.vAiBox.setSize(self.vAoBox.size() - QSizeF(20, 20))
        self.cWhBox.setSize(self.vAiBox.size() - QSizeF(20, 20))

        # center - shifted to the right slightly
        x = self.winBox.width() - (self.vIdBox.width() +
                                   self.vAiBox.width()) / 2.0
        self.cen = QPointF(x, self.winBox.height() / 2.0)

        # positions and initial settings
        self.vAoBox.moveCenter(self.cen)
        self.vAiBox.moveCenter(self.cen)
        self.cWhBox.moveCenter(self.cen)
        self.vIdBox.moveCenter(self.vIdCen)

        self.cW_rad = self.cWhBox.width() / 2.0
        self.ang_w = radians(self.s_ang) - radians(self.e_ang)

        # gradients
        colWhl = QConicalGradient(self.cen, self.o_ang)
        whl_cols = [
            Qt.red, Qt.magenta, Qt.blue, Qt.cyan, Qt.green, Qt.yellow, Qt.red
        ]
        for i, c in enumerate(whl_cols[::self.rot_d]):
            colWhl.setColorAt(i / 6.0, c)

        rad = min(self.cWhBox.width() / 2.0, self.cWhBox.height() / 2.0)
        cWhlFade = QRadialGradient(self.cen, rad, self.cen)
        cWhlFade.setColorAt(0, Qt.white)
        cWhlFade.setColorAt(1, QColor(255, 255, 255, 0))

        self.cWhlBrush1 = QBrush(colWhl)
        self.cWhlBrush2 = QBrush(cWhlFade)

        # painter paths (arcs, wheel)
        rad = self.vAoBox.width() / 2.0
        x, y = rad * cos(radians(self.s_ang)), -rad * sin(radians(self.s_ang))
        x += self.cen.x()
        y += self.cen.y()

        self.vArcPath = QPainterPath(QPointF(x, y))  # value arc (for color)
        self.vArcPath.arcTo(self.vAoBox, self.s_ang, self.e_ang - self.s_ang)
        self.vArcPath.arcTo(self.vAiBox, self.e_ang, self.s_ang - self.e_ang)
        self.vArcPath.closeSubpath()

        self.vInArcPath = QPainterPath(QPointF(x, y))  # value arc (for mouse)
        self.vInArcPath.arcTo(self.vIoBox, self.s_ang, self.e_ang - self.s_ang)
        self.vInArcPath.arcTo(self.vAiBox, self.e_ang, self.s_ang - self.e_ang)
        self.vInArcPath.closeSubpath()

        self.colWhlPath = QPainterPath()
        self.colWhlPath.addEllipse(self.cWhBox)