class FrameIndicator(QGraphicsItem): def __init__(self, size, frame_width, offset, y, color=red, parent=None): super(FrameIndicator, self).__init__(parent) self._size = size self._frame_width = frame_width self.y = y self.offset = offset self.view_rect = QRectF() self.setFrame(0) self.color = color def paint(self, painter, styleoptions, parent=None): brush = QBrush() brush.setColor(self.color) painter.setBrush(self.color) painter.drawRect(self._bounding_rect) def boundingRect(self): return self._bounding_rect def setFrame(self, idx): self.prepareGeometryChange() x = idx * self._frame_width + self.offset self._bounding_rect = QRectF() self._bounding_rect.setX(x) self._bounding_rect.setY(self.y) self._bounding_rect.setSize(self._size)
class TimeLine(QGraphicsItem): def __init__(self, label, indices, pos, length, height, label_width, frame_width, color, parent=None): super(TimeLine, self).__init__(parent) self._pos = pos self._length = length self._height = height self.label = label self._label_width = label_width self._indices = indices self.frame_width = frame_width size = QSizeF() size.setHeight(self._height) size.setWidth(self._length) self._bounding_rect = QRectF() self._bounding_rect.setX(self._pos.x()) self._bounding_rect.setY(self._pos.y()) self._bounding_rect.setSize(size) self._tpos = QPointF(pos) self._tpos.setY(pos.y() + self._height) self.color = QColor() self.color.setRed(color[0] * 255) self.color.setGreen(color[1] * 255) self.color.setBlue(color[2] * 255) self.color.setAlpha(255) def paint(self, painter, styleoptions, parent=None): #brush = QtGui.QBrush() #brush.setColor(blue) painter.setBrush(self.color) for idx in self._indices: x = self._pos.x() + self._label_width + self.frame_width * idx painter.drawRect(x, self._pos.y(), self.frame_width, self._height) #brush = QtGui.QBrush() #brush.setColor(red) painter.setBrush(black) painter.drawLine(self._pos.x(), self._pos.y(), self._pos.x() + self._length, self._pos.y()) painter.setPen(black) painter.setFont(QFont("Arial", 10)) painter.drawText(self._tpos, self.label) # QtCore.Qt.AlignCenter, def boundingRect(self): return self._bounding_rect
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)