def _gradient(self): gradient = QLinearGradient() gradient.setStart( (self._bounds.topLeft() + self._bounds.topRight()) / 2) gradient.setFinalStop( (self._bounds.bottomLeft() + self._bounds.bottomRight()) / 2) gradient.setColorAt(0, self._color) gradient.setColorAt(1, self._color.darker(200)) return gradient
class RoundRectItem(QGraphicsObject): def __init__(self, bounds, color, parent=None): super(RoundRectItem, self).__init__(parent) self.fillRect = False self.bounds = QRectF(bounds) self.pix = QPixmap() self.gradient = QLinearGradient() self.gradient.setStart(self.bounds.topLeft()) self.gradient.setFinalStop(self.bounds.bottomRight()) self.gradient.setColorAt(0, color) self.gradient.setColorAt(1, color.darker(200)) self.setCacheMode(QGraphicsItem.ItemCoordinateCache) def setFill(self, fill): self.fillRect = fill self.update() def fill(self): return self.fillRect fill = pyqtProperty(bool, fill, setFill) def paint(self, painter, option, widget): painter.setPen(Qt.NoPen) painter.setBrush(QColor(0, 0, 0, 64)) painter.drawRoundedRect(self.bounds.translated(2, 2), 25.0, 25.0) if self.fillRect: painter.setBrush(QApplication.palette().brush(QPalette.Window)) else: painter.setBrush(self.gradient) painter.setPen(QPen(Qt.black, 1)) painter.drawRoundedRect(self.bounds, 25.0, 25.0) if not self.pix.isNull(): painter.scale(1.95, 1.95) painter.drawPixmap(-self.pix.width() / 2, -self.pix.height() / 2, self.pix) def boundingRect(self): return self.bounds.adjusted(0, 0, 2, 2) def pixmap(self): return QPixmap(self.pix) def setPixmap(self, pixmap): self.pix = QPixmap(pixmap) self.update()
def paintEvent(self,e): # print(e) linear_gradient = QLinearGradient() linear_gradient.setStart(0, 10) #填充的起点坐标 linear_gradient.setFinalStop(0, 40) #填充的终点坐标 #第一个参数终点坐标,相对于我们上面的区域而言,按照比例进行计算 linear_gradient.setColorAt(0.1, QColor(14, 179, 255)) linear_gradient.setColorAt(0.5, QColor(114, 232, 255)) linear_gradient.setColorAt(0.9, QColor(14, 179, 255)) mask_linear_gradient = QLinearGradient() #遮罩的线性渐变填充 mask_linear_gradient.setStart(0, 10) mask_linear_gradient.setFinalStop(0, 40) # mask_linear_gradient.setColorAt(0.1, QColor(254, 113, 122)) # mask_linear_gradient.setColorAt(0.3, QColor(224, 246, 242)) mask_linear_gradient.setColorAt(0.1, QColor(14, 179, 255)) mask_linear_gradient.setColorAt(0.5, QColor(114, 232, 255)) # mask_linear_gradient.setColorAt(0.5, QColor(253, 147, 255)) # mask_linear_gradient.setColorAt(0.7, QColor(1, 1, 1)) # mask_linear_gradient.setColorAt(0.7, QColor(64, 2, 2)) mask_linear_gradient.setColorAt(0.9, QColor(14, 179, 255)) # mask_linear_gradient.setColorAt(1, QColor(0, 0, 0)) # print(e) # 设置字体 font = QFont() font.setFamily("文泉驿等宽微米黑") font.setBold(True) font.setPointSize(30) # self.q.setFont(font) p = QPainter(self) p.setFont(font); # p.setPen(QColor(0, 0, 0, 200)); # p.drawText(1, 1, 700, 60, Qt.AlignHCenter, "梦音乐梦音乐梦音乐"); #//左对齐 # // 再在上面绘制渐变文字 # p.setPen(QPen(linear_gradient, 0)); # p.drawText(0, 0, 800, 60, Qt.AlignHCenter, "梦音乐梦音乐梦音乐"); # SYL - 让我们用声音聆听彼此~ # if not self.s: # self.s = str("SYL - 让我们用声音聆听彼此~") # // 设置歌词遮罩 p.setPen(QPen(mask_linear_gradient, 0)); p.drawText(0, 0, 900, 60, Qt.AlignHCenter, self.text());
def toGradient(cls, data): """把字典转成渐变 :param cls: :param data: 字典数据 """ gtype = data.get('type', -1) if gtype == QGradient.LinearGradient: gradient = QLinearGradient() elif gtype == QGradient.RadialGradient: gradient = QRadialGradient() elif gtype == QGradient.ConicalGradient: gradient = QConicalGradient() else: gradient = QLinearGradient() gradient.setSpread(data.get('spread', QGradient.PadSpread)) gradient.setStart(data.get('start', QPointF(0, 0))) gradient.setFinalStop(data.get('finalStop', QPointF(1, 1))) stops = data.get('stops', None) if stops: gradient.setStops(stops) return gradient
def _create_linear_gradient(self) -> None: self._gradient_widget.setAutoFillBackground(True) gradient = QLinearGradient() gradient.setStart(self._gradient_widget.width(), 0.0) gradient.setFinalStop(self._gradient_widget.width(), self._gradient_widget.height()) # Create gradient stops stops = [] i = 0.0 for i in range(360): stop_location = i / 360.0 color = QColor.fromHsvF(i / 360.0, 1.0, 0.8) stop = (stop_location, color) stops.append(stop) gradient.setStops(stops) # Add Gradient to the rectangle brush = QtGui.QBrush(gradient) palette = self._gradient_widget.palette() palette.setBrush(self._gradient_widget.backgroundRole(), brush) self._gradient_widget.setPalette(palette)
class SwitchPrivate(QObject): def __init__(self, q, parent=None): QObject.__init__(self, parent=parent) self.mPointer = q self.mPosition = 0.0 self.mGradient = QLinearGradient() self.mGradient.setSpread(QGradient.PadSpread) self.animation = QPropertyAnimation(self) self.animation.setTargetObject(self) self.animation.setPropertyName(b'position') self.animation.setStartValue(0.0) self.animation.setEndValue(1.0) self.animation.setDuration(200) self.animation.setEasingCurve(QEasingCurve.InOutExpo) self.animation.finished.connect(self.mPointer.update) @pyqtProperty(float) def position(self): return self.mPosition @position.setter def position(self, value): self.mPosition = value self.mPointer.update() def draw(self, painter): r = self.mPointer.rect() margin = r.height() / 10 shadow = self.mPointer.palette().color(QPalette.Dark) light = self.mPointer.palette().color(QPalette.Light) button = self.mPointer.palette().color(QPalette.Button) painter.setPen(Qt.NoPen) self.mGradient.setColorAt(0, shadow.darker(130)) self.mGradient.setColorAt(1, light.darker(130)) self.mGradient.setStart(0, r.height()) self.mGradient.setFinalStop(0, 0) painter.setBrush(self.mGradient) painter.drawRoundedRect(r, r.height() / 2, r.height() / 2) self.mGradient.setColorAt(0, shadow.darker(140)) self.mGradient.setColorAt(1, light.darker(160)) self.mGradient.setStart(0, 0) self.mGradient.setFinalStop(0, r.height()) painter.setBrush(self.mGradient) painter.drawRoundedRect(r.adjusted(margin, margin, -margin, -margin), r.height() / 2, r.height() / 2) self.mGradient.setColorAt(0, button.darker(130)) self.mGradient.setColorAt(1, button) painter.setBrush(self.mGradient) x = r.height() / 2.0 + self.mPosition * (r.width() - r.height()) painter.drawEllipse(QPointF(x, r.height() / 2), r.height() / 2 - margin, r.height() / 2 - margin) @pyqtSlot(bool, name='animate') def animate(self, checked): self.animation.setDirection(QPropertyAnimation.Forward if checked else QPropertyAnimation.Backward) self.animation.start()
class PixmapDial(QDial): # enum CustomPaintMode CUSTOM_PAINT_MODE_NULL = 0 # default (NOTE: only this mode has label gradient) CUSTOM_PAINT_MODE_CARLA_WET = 1 # color blue-green gradient (reserved #3) CUSTOM_PAINT_MODE_CARLA_VOL = 2 # color blue (reserved #3) CUSTOM_PAINT_MODE_CARLA_L = 3 # color yellow (reserved #4) CUSTOM_PAINT_MODE_CARLA_R = 4 # color yellow (reserved #4) CUSTOM_PAINT_MODE_CARLA_PAN = 5 # color yellow (reserved #3) CUSTOM_PAINT_MODE_COLOR = 6 # color, selectable (reserved #3) CUSTOM_PAINT_MODE_ZITA = 7 # custom zita knob (reserved #6) CUSTOM_PAINT_MODE_NO_GRADIENT = 8 # skip label gradient # enum Orientation HORIZONTAL = 0 VERTICAL = 1 HOVER_MIN = 0 HOVER_MAX = 9 MODE_DEFAULT = 0 MODE_LINEAR = 1 # signals realValueChanged = pyqtSignal(float) def __init__(self, parent, index=0): QDial.__init__(self, parent) self.fDialMode = self.MODE_LINEAR self.fMinimum = 0.0 self.fMaximum = 1.0 self.fRealValue = 0.0 self.fPrecision = 10000 self.fIsInteger = False self.fIsHovered = False self.fIsPressed = False self.fHoverStep = self.HOVER_MIN self.fLastDragPos = None self.fLastDragValue = 0.0 self.fIndex = index self.fPixmap = QPixmap(":/bitmaps/dial_01d.png") self.fPixmapNum = "01" if self.fPixmap.width() > self.fPixmap.height(): self.fPixmapOrientation = self.HORIZONTAL else: self.fPixmapOrientation = self.VERTICAL self.fLabel = "" self.fLabelPos = QPointF(0.0, 0.0) self.fLabelFont = QFont(self.font()) self.fLabelFont.setPixelSize(8) self.fLabelWidth = 0 self.fLabelHeight = 0 if self.palette().window().color().lightness() > 100: # Light background c = self.palette().dark().color() self.fLabelGradientColor1 = c self.fLabelGradientColor2 = QColor(c.red(), c.green(), c.blue(), 0) self.fLabelGradientColorT = [self.palette().buttonText().color(), self.palette().mid().color()] else: # Dark background self.fLabelGradientColor1 = QColor(0, 0, 0, 255) self.fLabelGradientColor2 = QColor(0, 0, 0, 0) self.fLabelGradientColorT = [Qt.white, Qt.darkGray] self.fLabelGradient = QLinearGradient(0, 0, 0, 1) self.fLabelGradient.setColorAt(0.0, self.fLabelGradientColor1) self.fLabelGradient.setColorAt(0.6, self.fLabelGradientColor1) self.fLabelGradient.setColorAt(1.0, self.fLabelGradientColor2) self.fLabelGradientRect = QRectF(0.0, 0.0, 0.0, 0.0) self.fCustomPaintMode = self.CUSTOM_PAINT_MODE_NULL self.fCustomPaintColor = QColor(0xff, 0xff, 0xff) self.updateSizes() # Fake internal value, custom precision QDial.setMinimum(self, 0) QDial.setMaximum(self, self.fPrecision) QDial.setValue(self, 0) self.valueChanged.connect(self.slot_valueChanged) def getIndex(self): return self.fIndex def getBaseSize(self): return self.fPixmapBaseSize def forceWhiteLabelGradientText(self): self.fLabelGradientColor1 = QColor(0, 0, 0, 255) self.fLabelGradientColor2 = QColor(0, 0, 0, 0) self.fLabelGradientColorT = [Qt.white, Qt.darkGray] def setLabelColor(self, enabled, disabled): self.fLabelGradientColor1 = QColor(0, 0, 0, 255) self.fLabelGradientColor2 = QColor(0, 0, 0, 0) self.fLabelGradientColorT = [enabled, disabled] def updateSizes(self): self.fPixmapWidth = self.fPixmap.width() self.fPixmapHeight = self.fPixmap.height() if self.fPixmapWidth < 1: self.fPixmapWidth = 1 if self.fPixmapHeight < 1: self.fPixmapHeight = 1 if self.fPixmapOrientation == self.HORIZONTAL: self.fPixmapBaseSize = self.fPixmapHeight self.fPixmapLayersCount = self.fPixmapWidth / self.fPixmapHeight else: self.fPixmapBaseSize = self.fPixmapWidth self.fPixmapLayersCount = self.fPixmapHeight / self.fPixmapWidth self.setMinimumSize(self.fPixmapBaseSize, self.fPixmapBaseSize + self.fLabelHeight + 5) self.setMaximumSize(self.fPixmapBaseSize, self.fPixmapBaseSize + self.fLabelHeight + 5) if not self.fLabel: self.fLabelHeight = 0 self.fLabelWidth = 0 return self.fLabelWidth = QFontMetrics(self.fLabelFont).width(self.fLabel) self.fLabelHeight = QFontMetrics(self.fLabelFont).height() self.fLabelPos.setX(float(self.fPixmapBaseSize)/2.0 - float(self.fLabelWidth)/2.0) if self.fPixmapNum in ("01", "02", "07", "08", "09", "10"): self.fLabelPos.setY(self.fPixmapBaseSize + self.fLabelHeight) elif self.fPixmapNum in ("11",): self.fLabelPos.setY(self.fPixmapBaseSize + self.fLabelHeight*2/3) else: self.fLabelPos.setY(self.fPixmapBaseSize + self.fLabelHeight/2) self.fLabelGradient.setStart(0, float(self.fPixmapBaseSize)/2.0) self.fLabelGradient.setFinalStop(0, self.fPixmapBaseSize + self.fLabelHeight + 5) self.fLabelGradientRect = QRectF(float(self.fPixmapBaseSize)/8.0, float(self.fPixmapBaseSize)/2.0, float(self.fPixmapBaseSize*3)/4.0, self.fPixmapBaseSize+self.fLabelHeight+5) def setCustomPaintMode(self, paintMode): if self.fCustomPaintMode == paintMode: return self.fCustomPaintMode = paintMode self.update() def setCustomPaintColor(self, color): if self.fCustomPaintColor == color: return self.fCustomPaintColor = color self.update() def setLabel(self, label): if self.fLabel == label: return self.fLabel = label self.updateSizes() self.update() def setIndex(self, index): self.fIndex = index 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.fPixmapOrientation = self.HORIZONTAL else: self.fPixmapOrientation = self.VERTICAL # special pixmaps if self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_NULL: # reserved for carla-wet, carla-vol, carla-pan and color if self.fPixmapNum == "03": self.fCustomPaintMode = self.CUSTOM_PAINT_MODE_COLOR # reserved for carla-L and carla-R elif self.fPixmapNum == "04": self.fCustomPaintMode = self.CUSTOM_PAINT_MODE_CARLA_L # reserved for zita elif self.fPixmapNum == "06": self.fCustomPaintMode = self.CUSTOM_PAINT_MODE_ZITA self.updateSizes() self.update() def setPrecision(self, value, isInteger): self.fPrecision = value self.fIsInteger = isInteger QDial.setMaximum(self, value) def setMinimum(self, value): self.fMinimum = value def setMaximum(self, value): self.fMaximum = value def setValue(self, value, emitSignal=False): if self.fRealValue == value: return if value <= self.fMinimum: qtValue = 0 self.fRealValue = self.fMinimum elif value >= self.fMaximum: qtValue = self.fPrecision self.fRealValue = self.fMaximum else: qtValue = round(float(value - self.fMinimum) / float(self.fMaximum - self.fMinimum) * self.fPrecision) self.fRealValue = value # Block change signal, we'll handle it ourselves self.blockSignals(True) QDial.setValue(self, qtValue) self.blockSignals(False) if emitSignal: self.realValueChanged.emit(self.fRealValue) @pyqtSlot(int) def slot_valueChanged(self, value): self.fRealValue = float(value)/self.fPrecision * (self.fMaximum - self.fMinimum) + self.fMinimum self.realValueChanged.emit(self.fRealValue) @pyqtSlot() def slot_updatePixmap(self): self.setPixmap(int(self.fPixmapNum)) def minimumSizeHint(self): return QSize(self.fPixmapBaseSize, self.fPixmapBaseSize) def sizeHint(self): return QSize(self.fPixmapBaseSize, self.fPixmapBaseSize) def changeEvent(self, event): QDial.changeEvent(self, event) # Force pixmap update if enabled state changes if event.type() == QEvent.EnabledChange: self.setPixmap(int(self.fPixmapNum)) def enterEvent(self, event): self.fIsHovered = True if self.fHoverStep == self.HOVER_MIN: self.fHoverStep = self.HOVER_MIN + 1 QDial.enterEvent(self, event) def leaveEvent(self, event): self.fIsHovered = False if self.fHoverStep == self.HOVER_MAX: self.fHoverStep = self.HOVER_MAX - 1 QDial.leaveEvent(self, event) def mousePressEvent(self, event): if self.fDialMode == self.MODE_DEFAULT: return QDial.mousePressEvent(self, event) if event.button() == Qt.LeftButton: self.fIsPressed = True self.fLastDragPos = event.pos() self.fLastDragValue = self.fRealValue def mouseMoveEvent(self, event): if self.fDialMode == self.MODE_DEFAULT: return QDial.mouseMoveEvent(self, event) if not self.fIsPressed: return range = (self.fMaximum - self.fMinimum) / 4.0 pos = event.pos() dx = range * float(pos.x() - self.fLastDragPos.x()) / self.width() dy = range * float(pos.y() - self.fLastDragPos.y()) / self.height() value = self.fLastDragValue + dx - dy if value < self.fMinimum: value = self.fMinimum elif value > self.fMaximum: value = self.fMaximum elif self.fIsInteger: value = float(round(value)) self.setValue(value, True) def mouseReleaseEvent(self, event): if self.fDialMode == self.MODE_DEFAULT: return QDial.mouseReleaseEvent(self, event) if self.fIsPressed: self.fIsPressed = False def paintEvent(self, event): painter = QPainter(self) event.accept() painter.save() painter.setRenderHint(QPainter.Antialiasing, True) if self.fLabel: if self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_NULL: painter.setPen(self.fLabelGradientColor2) painter.setBrush(self.fLabelGradient) painter.drawRect(self.fLabelGradientRect) painter.setFont(self.fLabelFont) painter.setPen(self.fLabelGradientColorT[0 if self.isEnabled() else 1]) painter.drawText(self.fLabelPos, self.fLabel) if self.isEnabled(): normValue = float(self.fRealValue - self.fMinimum) / float(self.fMaximum - self.fMinimum) target = QRectF(0.0, 0.0, self.fPixmapBaseSize, self.fPixmapBaseSize) curLayer = int((self.fPixmapLayersCount - 1) * normValue) if self.fPixmapOrientation == self.HORIZONTAL: xpos = self.fPixmapBaseSize * curLayer ypos = 0.0 else: xpos = 0.0 ypos = self.fPixmapBaseSize * curLayer source = QRectF(xpos, ypos, self.fPixmapBaseSize, self.fPixmapBaseSize) painter.drawPixmap(target, self.fPixmap, source) # Custom knobs (Dry/Wet and Volume) if self.fCustomPaintMode in (self.CUSTOM_PAINT_MODE_CARLA_WET, self.CUSTOM_PAINT_MODE_CARLA_VOL): # knob color colorGreen = QColor(0x5D, 0xE7, 0x3D).lighter(100 + self.fHoverStep*6) colorBlue = QColor(0x3E, 0xB8, 0xBE).lighter(100 + self.fHoverStep*6) # 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*normValue) ballValue = tmpValue - floor(tmpValue) ballPoint = ballPath.pointAtPercent(ballValue) # draw arc startAngle = 216*16 spanAngle = -252*16*normValue if self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_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.fCustomPaintMode in (self.CUSTOM_PAINT_MODE_CARLA_L, self.CUSTOM_PAINT_MODE_CARLA_R): # knob color color = QColor(0xAD, 0xD5, 0x48).lighter(100 + self.fHoverStep*6) # 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*normValue) 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.fCustomPaintMode == self.CUSTOM_PAINT_MODE_CARLA_L: startAngle = 216*16 spanAngle = -252.0*16*normValue else: startAngle = 324.0*16 spanAngle = 252.0*16*(1.0-normValue) painter.setPen(QPen(color, 2)) painter.drawArc(3.5, 4.5, 22.0, 22.0, startAngle, spanAngle) # Custom knobs (Color) elif self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_COLOR: # knob color color = self.fCustomPaintColor.lighter(100 + self.fHoverStep*6) # draw small circle ballRect = QRectF(8.0, 8.0, 15.0, 15.0) ballPath = QPainterPath() ballPath.addEllipse(ballRect) tmpValue = (0.375 + 0.75*normValue) ballValue = tmpValue - floor(tmpValue) ballPoint = ballPath.pointAtPercent(ballValue) # draw arc startAngle = 216*16 spanAngle = -252*16*normValue painter.setBrush(color) painter.setPen(QPen(color, 0)) painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.2, 2.2)) painter.setBrush(color) painter.setPen(QPen(color, 3)) painter.drawArc(4.0, 4.0, 26.0, 26.0, startAngle, spanAngle) # Custom knobs (Zita) elif self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_ZITA: a = normValue * pi * 1.5 - 2.35 r = 10.0 x = 10.5 y = 10.5 x += r * sin(a) y -= r * cos(a) painter.setBrush(Qt.black) painter.setPen(QPen(Qt.black, 2)) painter.drawLine(QPointF(11.0, 11.0), QPointF(x, y)) # Custom knobs else: painter.restore() return if self.HOVER_MIN < self.fHoverStep < self.HOVER_MAX: self.fHoverStep += 1 if self.fIsHovered else -1 QTimer.singleShot(20, self.update) else: # isEnabled() target = QRectF(0.0, 0.0, self.fPixmapBaseSize, self.fPixmapBaseSize) painter.drawPixmap(target, self.fPixmap, target) painter.restore() def resizeEvent(self, event): QDial.resizeEvent(self, event) self.updateSizes()
class DQuickWidget(FMoveableWidget): def __init__(self): super(DQuickWidget, self).__init__() self.resize(1000, 100) self.setMinimumSize(100, 80) self.linear_gradient = QLinearGradient() self.linear_gradient.setStart(0, 10) self.linear_gradient.setFinalStop(0, 40) self.linear_gradient.setColorAt(0.1, QColor(14, 179, 255)); self.linear_gradient.setColorAt(0.5, QColor(114, 232, 255)); self.linear_gradient.setColorAt(0.9, QColor(14, 179, 255)); self.mask_linear_gradient = QLinearGradient() self.mask_linear_gradient.setStart(0, 10) self.mask_linear_gradient.setFinalStop(0, 40) self.mask_linear_gradient.setColorAt(0.1, QColor(222, 54, 4)) self.mask_linear_gradient.setColorAt(0.5, QColor(255, 72, 16)) self.mask_linear_gradient.setColorAt(0.9, QColor(222, 54, 4)) self.text = "PyQt 5.2版本最新发布了,Qt 库的Python绑定" self.font = QFont() self.font.setFamily("Times New Roman") self.font.setBold(True) self.font.setPixelSize(30) self.setFont(self.font) self.timer = QTimer(self) self.timer.setInterval(100) self.timer.timeout.connect(self.update) self.timer.start() self.textWidth = self.fontMetrics().width(self.text) self.textHeight = self.fontMetrics().height() self.p = 0.1 self.button = QPushButton('1111', self) self.button.move(100, 0) self.button.resize(40, 40) self.toolBarHeight = 50 def paintEvent(self, event): self.startX = (self.width() - self.textWidth) / 2 self.startY = self.toolBarHeight + (self.height() - self.toolBarHeight - self.textHeight) / 2 painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) # pixelSize = self.font.pixelSize() # pixelSize += 1 # self.font.setPixelSize(pixelSize) # self.setFont(self.font) # self.textHeight = self.fontMetrics().height() # spacing = (self.height() - self.toolBarHeight - self.textHeight) / 2 # # if spacing > 0: painter.setFont(self.font) if self.boderFlag: color = QColor('lightgray') color.setAlpha(30) painter.fillRect(0, self.toolBarHeight, self.width(), self.height() - self.toolBarHeight, color) painter.setPen(QColor(0, 0, 0, 200)) painter.drawText(self.startX + 1, self.startY + 1, self.textWidth, self.textHeight, Qt.AlignLeft, self.text) painter.setPen(QPen(self.linear_gradient, 0)) painter.drawText(self.startX, self.startY, self.textWidth, self.textHeight, Qt.AlignLeft, self.text) painter.setPen(QPen(self.mask_linear_gradient, 0)) painter.drawText(self.startX, self.startY, self.textWidth * self.p , self.textHeight, Qt.AlignLeft, self.text) self.p += 0.01 if self.p >= 1: self.p = 0 self.font.setPixelSize(30)
class PixmapDial(QDial): # enum CustomPaintMode CUSTOM_PAINT_MODE_NULL = 0 # default (NOTE: only this mode has label gradient) CUSTOM_PAINT_MODE_CARLA_WET = 1 # color blue-green gradient (reserved #3) CUSTOM_PAINT_MODE_CARLA_VOL = 2 # color blue (reserved #3) CUSTOM_PAINT_MODE_CARLA_L = 3 # color yellow (reserved #4) CUSTOM_PAINT_MODE_CARLA_R = 4 # color yellow (reserved #4) CUSTOM_PAINT_MODE_CARLA_PAN = 5 # color yellow (reserved #3) CUSTOM_PAINT_MODE_COLOR = 6 # color, selectable (reserved #3) CUSTOM_PAINT_MODE_ZITA = 7 # custom zita knob (reserved #6) CUSTOM_PAINT_MODE_NO_GRADIENT = 8 # skip label gradient # enum Orientation HORIZONTAL = 0 VERTICAL = 1 HOVER_MIN = 0 HOVER_MAX = 9 # signals realValueChanged = pyqtSignal(float) def __init__(self, parent, index=0): QDial.__init__(self, parent) self.fMinimum = 0.0 self.fMaximum = 1.0 self.fRealValue = 0.0 self.fIsHovered = False self.fHoverStep = self.HOVER_MIN self.fIndex = index self.fPixmap = QPixmap(":/bitmaps/dial_01d.png") self.fPixmapNum = "01" if self.fPixmap.width() > self.fPixmap.height(): self.fPixmapOrientation = self.HORIZONTAL else: self.fPixmapOrientation = self.VERTICAL self.fLabel = "" self.fLabelPos = QPointF(0.0, 0.0) self.fLabelFont = QFont(self.font()) self.fLabelFont.setPointSize(6) self.fLabelWidth = 0 self.fLabelHeight = 0 if self.palette().window().color().lightness() > 100: # Light background c = self.palette().dark().color() self.fLabelGradientColor1 = c self.fLabelGradientColor2 = QColor(c.red(), c.green(), c.blue(), 0) self.fLabelGradientColorT = [self.palette().buttonText().color(), self.palette().mid().color()] else: # Dark background self.fLabelGradientColor1 = QColor(0, 0, 0, 255) self.fLabelGradientColor2 = QColor(0, 0, 0, 0) self.fLabelGradientColorT = [Qt.white, Qt.darkGray] self.fLabelGradient = QLinearGradient(0, 0, 0, 1) self.fLabelGradient.setColorAt(0.0, self.fLabelGradientColor1) self.fLabelGradient.setColorAt(0.6, self.fLabelGradientColor1) self.fLabelGradient.setColorAt(1.0, self.fLabelGradientColor2) self.fLabelGradientRect = QRectF(0.0, 0.0, 0.0, 0.0) self.fCustomPaintMode = self.CUSTOM_PAINT_MODE_NULL self.fCustomPaintColor = QColor(0xff, 0xff, 0xff) self.updateSizes() # Fake internal value, 10'000 precision QDial.setMinimum(self, 0) QDial.setMaximum(self, 10000) QDial.setValue(self, 0) self.valueChanged.connect(self.slot_valueChanged) def getIndex(self): return self.fIndex def getBaseSize(self): return self.fPixmapBaseSize def forceWhiteLabelGradientText(self): self.fLabelGradientColor1 = QColor(0, 0, 0, 255) self.fLabelGradientColor2 = QColor(0, 0, 0, 0) self.fLabelGradientColorT = [Qt.white, Qt.darkGray] def updateSizes(self): self.fPixmapWidth = self.fPixmap.width() self.fPixmapHeight = self.fPixmap.height() if self.fPixmapWidth < 1: self.fPixmapWidth = 1 if self.fPixmapHeight < 1: self.fPixmapHeight = 1 if self.fPixmapOrientation == self.HORIZONTAL: self.fPixmapBaseSize = self.fPixmapHeight self.fPixmapLayersCount = self.fPixmapWidth / self.fPixmapHeight else: self.fPixmapBaseSize = self.fPixmapWidth self.fPixmapLayersCount = self.fPixmapHeight / self.fPixmapWidth self.setMinimumSize(self.fPixmapBaseSize, self.fPixmapBaseSize + self.fLabelHeight + 5) self.setMaximumSize(self.fPixmapBaseSize, self.fPixmapBaseSize + self.fLabelHeight + 5) if not self.fLabel: self.fLabelHeight = 0 self.fLabelWidth = 0 return self.fLabelWidth = QFontMetrics(self.fLabelFont).width(self.fLabel) self.fLabelHeight = QFontMetrics(self.fLabelFont).height() self.fLabelPos.setX(float(self.fPixmapBaseSize)/2.0 - float(self.fLabelWidth)/2.0) if self.fPixmapNum in ("01", "02", "07", "08", "09", "10"): self.fLabelPos.setY(self.fPixmapBaseSize + self.fLabelHeight) elif self.fPixmapNum in ("11",): self.fLabelPos.setY(self.fPixmapBaseSize + self.fLabelHeight*2/3) else: self.fLabelPos.setY(self.fPixmapBaseSize + self.fLabelHeight/2) self.fLabelGradient.setStart(0, float(self.fPixmapBaseSize)/2.0) self.fLabelGradient.setFinalStop(0, self.fPixmapBaseSize + self.fLabelHeight + 5) self.fLabelGradientRect = QRectF(float(self.fPixmapBaseSize)/8.0, float(self.fPixmapBaseSize)/2.0, float(self.fPixmapBaseSize*3)/4.0, self.fPixmapBaseSize+self.fLabelHeight+5) def setCustomPaintMode(self, paintMode): if self.fCustomPaintMode == paintMode: return self.fCustomPaintMode = paintMode self.update() def setCustomPaintColor(self, color): if self.fCustomPaintColor == color: return self.fCustomPaintColor = color self.update() def setLabel(self, label): if self.fLabel == label: return self.fLabel = label self.updateSizes() self.update() def setIndex(self, index): self.fIndex = index 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.fPixmapOrientation = self.HORIZONTAL else: self.fPixmapOrientation = self.VERTICAL # special pixmaps if self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_NULL: # reserved for carla-wet, carla-vol, carla-pan and color if self.fPixmapNum == "03": self.fCustomPaintMode = self.CUSTOM_PAINT_MODE_COLOR # reserved for carla-L and carla-R elif self.fPixmapNum == "04": self.fCustomPaintMode = self.CUSTOM_PAINT_MODE_CARLA_L # reserved for zita elif self.fPixmapNum == "06": self.fCustomPaintMode = self.CUSTOM_PAINT_MODE_ZITA self.updateSizes() self.update() def setMinimum(self, value): self.fMinimum = value def setMaximum(self, value): self.fMaximum = value def setValue(self, value): if self.fRealValue == value: return self.fRealValue = value normValue = float(value - self.fMinimum) / float(self.fMaximum - self.fMinimum) QDial.setValue(self, int(normValue * 10000)) @pyqtSlot(int) def slot_valueChanged(self, value): self.fRealValue = float(value)/10000.0 * (self.fMaximum - self.fMinimum) + self.fMinimum self.realValueChanged.emit(self.fRealValue) @pyqtSlot() def slot_updatePixmap(self): self.setPixmap(int(self.fPixmapNum)) def minimumSizeHint(self): return QSize(self.fPixmapBaseSize, self.fPixmapBaseSize) def sizeHint(self): return QSize(self.fPixmapBaseSize, self.fPixmapBaseSize) def changeEvent(self, event): QDial.changeEvent(self, event) # Force pixmap update if enabled state changes if event.type() == QEvent.EnabledChange: self.setPixmap(int(self.fPixmapNum)) def enterEvent(self, event): self.fIsHovered = True if self.fHoverStep == self.HOVER_MIN: self.fHoverStep = self.HOVER_MIN + 1 QDial.enterEvent(self, event) def leaveEvent(self, event): self.fIsHovered = False if self.fHoverStep == self.HOVER_MAX: self.fHoverStep = self.HOVER_MAX - 1 QDial.leaveEvent(self, event) def paintEvent(self, event): painter = QPainter(self) event.accept() painter.save() painter.setRenderHint(QPainter.Antialiasing, True) if self.fLabel: if self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_NULL: painter.setPen(self.fLabelGradientColor2) painter.setBrush(self.fLabelGradient) painter.drawRect(self.fLabelGradientRect) painter.setFont(self.fLabelFont) painter.setPen(self.fLabelGradientColorT[0 if self.isEnabled() else 1]) painter.drawText(self.fLabelPos, self.fLabel) if self.isEnabled(): normValue = float(self.fRealValue - self.fMinimum) / float(self.fMaximum - self.fMinimum) target = QRectF(0.0, 0.0, self.fPixmapBaseSize, self.fPixmapBaseSize) curLayer = int((self.fPixmapLayersCount - 1) * normValue) if self.fPixmapOrientation == self.HORIZONTAL: xpos = self.fPixmapBaseSize * curLayer ypos = 0.0 else: xpos = 0.0 ypos = self.fPixmapBaseSize * curLayer source = QRectF(xpos, ypos, self.fPixmapBaseSize, self.fPixmapBaseSize) painter.drawPixmap(target, self.fPixmap, source) # Custom knobs (Dry/Wet and Volume) if self.fCustomPaintMode in (self.CUSTOM_PAINT_MODE_CARLA_WET, self.CUSTOM_PAINT_MODE_CARLA_VOL): # knob color colorGreen = QColor(0x5D, 0xE7, 0x3D).lighter(100 + self.fHoverStep*6) colorBlue = QColor(0x3E, 0xB8, 0xBE).lighter(100 + self.fHoverStep*6) # 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*normValue) ballValue = tmpValue - floor(tmpValue) ballPoint = ballPath.pointAtPercent(ballValue) # draw arc startAngle = 216*16 spanAngle = -252*16*normValue if self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_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.fCustomPaintMode in (self.CUSTOM_PAINT_MODE_CARLA_L, self.CUSTOM_PAINT_MODE_CARLA_R): # knob color color = QColor(0xAD, 0xD5, 0x48).lighter(100 + self.fHoverStep*6) # 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*normValue) 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.fCustomPaintMode == self.CUSTOM_PAINT_MODE_CARLA_L: startAngle = 216*16 spanAngle = -252.0*16*normValue else: startAngle = 324.0*16 spanAngle = 252.0*16*(1.0-normValue) painter.setPen(QPen(color, 2)) painter.drawArc(3.5, 4.5, 22.0, 22.0, startAngle, spanAngle) # Custom knobs (Color) elif self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_COLOR: # knob color color = self.fCustomPaintColor.lighter(100 + self.fHoverStep*6) # draw small circle ballRect = QRectF(8.0, 8.0, 15.0, 15.0) ballPath = QPainterPath() ballPath.addEllipse(ballRect) tmpValue = (0.375 + 0.75*normValue) ballValue = tmpValue - floor(tmpValue) ballPoint = ballPath.pointAtPercent(ballValue) # draw arc startAngle = 216*16 spanAngle = -252*16*normValue painter.setBrush(color) painter.setPen(QPen(color, 0)) painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.2, 2.2)) painter.setBrush(color) painter.setPen(QPen(color, 3)) painter.drawArc(4.0, 4.0, 26.0, 26.0, startAngle, spanAngle) # Custom knobs (Zita) elif self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_ZITA: a = normValue * pi * 1.5 - 2.35 r = 10.0 x = 10.5 y = 10.5 x += r * sin(a) y -= r * cos(a) painter.setBrush(Qt.black) painter.setPen(QPen(Qt.black, 2)) painter.drawLine(QPointF(11.0, 11.0), QPointF(x, y)) # Custom knobs else: painter.restore() return if self.HOVER_MIN < self.fHoverStep < self.HOVER_MAX: self.fHoverStep += 1 if self.fIsHovered else -1 QTimer.singleShot(20, self.update) else: # isEnabled() target = QRectF(0.0, 0.0, self.fPixmapBaseSize, self.fPixmapBaseSize) painter.drawPixmap(target, self.fPixmap, target) painter.restore() def resizeEvent(self, event): QDial.resizeEvent(self, event) self.updateSizes()
class QDbMeter(QWidget): DB_MIN = int(config["DbMeter"]["dbMin"]) DB_MAX = int(config["DbMeter"]["dbMax"]) DB_CLIP = int(config["DbMeter"]["dbClip"]) def __init__(self, parent): super().__init__(parent) self.grad = QLinearGradient() self.grad.setColorAt(0, QColor(0, 255, 0)) # Green self.grad.setColorAt(0.5, QColor(255, 255, 0)) # Yellow self.grad.setColorAt(1, QColor(255, 0, 0)) # Red self.reset() def reset(self): self.peaks = [self.DB_MIN, self.DB_MIN] self.rmss = [self.DB_MIN, self.DB_MIN] self.decPeak = [self.DB_MIN, self.DB_MIN] self.clipping = {} self.repaint() @QtCore.pyqtSlot(list, list, list) def plot(self, peaks, rms, decPeak): if(len(peaks) == 1): self.peaks = peaks * 2 self.rmss = rms * 2 self.decPeak = decPeak * 2 else: self.peaks = peaks self.rmss = rms self.decPeak = decPeak self.repaint() def paintEvent(self, e): if not self.visibleRegion().isEmpty(): # Stretch factor mul = (self.height() - 4) mul /= (self.DB_MAX - self.DB_MIN) peaks = [] for n, peak in enumerate(self.peaks): if peak > self.DB_CLIP: self.clipping[n] = True if peak < self.DB_MIN: peak = self.DB_MIN elif peak > self.DB_MAX: peak = self.DB_MAX peaks.append(round((peak - self.DB_MIN) * mul)) rmss = [] for n, rms in enumerate(self.rmss): if rms < self.DB_MIN: rms = self.DB_MIN elif rms > self.DB_MAX: rms = self.DB_MAX rmss.append(round((rms - self.DB_MIN) * mul)) decPeaks = [] for decPeak in self.decPeak: if decPeak < self.DB_MIN: decPeak = self.DB_MIN elif decPeak > self.DB_MAX: decPeak = self.DB_MAX decPeaks.append(round((decPeak - self.DB_MIN) * mul)) qp = QPainter() qp.begin(self) qp.setBrush(QColor(0, 0, 0, 0)) xpos = 0 xdim = self.width() / len(peaks) for n in range(len(peaks)): peak = peaks[n] rms = rmss[n] decPeak = decPeaks[n] # Maximum "peak-rect" size maxRect = QtCore.QRect(xpos, self.height() - 2, xdim - 2, 2 - self.height()) # Set QLinearGradient start and final-stop position self.grad.setStart(maxRect.topLeft()) self.grad.setFinalStop(maxRect.bottomRight()) # Draw peak (audio peak in dB) rect = QtCore.QRect(xpos, self.height() - 2, xdim - 2, -peak) qp.setOpacity(0.6) qp.fillRect(rect, self.grad) qp.setOpacity(1.0) # Draw rms (in db) rect = QtCore.QRect(xpos, self.height() - 2, xdim - 2, -rms) qp.fillRect(rect, self.grad) # Draw decay peak decRect = QtCore.QRect(xpos, (self.height() - 3) - decPeak, xdim - 2, 2) qp.fillRect(decRect, self.grad) # Draw Borders if self.clipping.get(n, False): qp.setPen(QColor(200, 0, 0)) else: qp.setPen(QColor(100, 100, 100)) qp.drawRect(maxRect) xpos += xdim qp.end()
class DigitalPeakMeter(QWidget): # enum Orientation HORIZONTAL = 1 VERTICAL = 2 # enum Color GREEN = 1 BLUE = 2 def __init__(self, parent): QWidget.__init__(self, parent) self.fChannels = 0 self.fDrawLines = True self.fOrientation = self.VERTICAL self.fSmoothMultiplier = 1 self.fColorBackground = QColor("#111111") self.fGradientMeter = QLinearGradient(0, 0, 1, 1) self.setChannels(0) self.setColor(self.GREEN) def displayMeter(self, meter, level, forced = False): if meter <= 0 or meter > self.fChannels: return qCritical("DigitalPeakMeter::displayMeter(%i, %f) - invalid meter number" % (meter, level)) if not isinstance(level, float): return qCritical("DigitalPeakMeter::displayMeter(%i, %f) - meter value must be float" % (meter, level)) i = meter - 1 if self.fSmoothMultiplier > 0 and not forced: level = (self.fLastValueData[i] * self.fSmoothMultiplier + level) / float(self.fSmoothMultiplier + 1) if level < 0.001: level = 0.0 elif level > 0.999: level = 1.0 if self.fChannelsData[i] != level: self.fChannelsData[i] = level self.update() self.fLastValueData[i] = level def setChannels(self, channels): if channels < 0: return qCritical("DigitalPeakMeter::setChannels(%i) - 'channels' must be a positive integer" % channels) self.fChannels = channels self.fChannelsData = [] self.fLastValueData = [] for x in range(channels): self.fChannelsData.append(0.0) self.fLastValueData.append(0.0) def setColor(self, color): if color == self.GREEN: self.fColorBase = QColor(93, 231, 61) self.fColorBaseAlt = QColor(15, 110, 15, 100) elif color == self.BLUE: self.fColorBase = QColor(82, 238, 248) self.fColorBaseAlt = QColor(15, 15, 110, 100) else: return qCritical("DigitalPeakMeter::setColor(%i) - invalid color" % color) self.setOrientation(self.fOrientation) def setLinesEnabled(self, yesNo): self.fDrawLines = yesNo def setOrientation(self, orientation): self.fOrientation = orientation if self.fOrientation == self.HORIZONTAL: self.fGradientMeter.setColorAt(0.0, self.fColorBase) self.fGradientMeter.setColorAt(0.2, self.fColorBase) self.fGradientMeter.setColorAt(0.4, self.fColorBase) self.fGradientMeter.setColorAt(0.6, self.fColorBase) self.fGradientMeter.setColorAt(0.8, Qt.yellow) self.fGradientMeter.setColorAt(1.0, Qt.red) elif self.fOrientation == self.VERTICAL: self.fGradientMeter.setColorAt(0.0, Qt.red) self.fGradientMeter.setColorAt(0.2, Qt.yellow) self.fGradientMeter.setColorAt(0.4, self.fColorBase) self.fGradientMeter.setColorAt(0.6, self.fColorBase) self.fGradientMeter.setColorAt(0.8, self.fColorBase) self.fGradientMeter.setColorAt(1.0, self.fColorBase) else: return qCritical("DigitalPeakMeter::setOrientation(%i) - invalid orientation" % orientation) self.updateSizes() def setSmoothRelease(self, value): if value < 0: value = 0 elif value > 5: value = 5 self.fSmoothMultiplier = value def minimumSizeHint(self): return QSize(10, 10) def sizeHint(self): return QSize(self.fWidth, self.fHeight) def updateSizes(self): self.fWidth = self.width() self.fHeight = self.height() self.fSizeMeter = 0 if self.fOrientation == self.HORIZONTAL: self.fGradientMeter.setFinalStop(self.fWidth, 0) if self.fChannels > 0: self.fSizeMeter = self.fHeight / self.fChannels elif self.fOrientation == self.VERTICAL: self.fGradientMeter.setFinalStop(0, self.fHeight) if self.fChannels > 0: self.fSizeMeter = self.fWidth / self.fChannels def paintEvent(self, event): painter = QPainter(self) event.accept() painter.setPen(Qt.black) painter.setBrush(Qt.black) painter.drawRect(0, 0, self.fWidth, self.fHeight) meterX = 0 painter.setPen(self.fColorBackground) painter.setBrush(self.fGradientMeter) for i in range(self.fChannels): level = self.fChannelsData[i] if self.fOrientation == self.HORIZONTAL: value = level * float(self.fWidth) elif self.fOrientation == self.VERTICAL: value = float(self.fHeight) - (level * float(self.fHeight)) else: value = 0.0 if self.fOrientation == self.HORIZONTAL: painter.drawRect(0, meterX, int(value), self.fSizeMeter) elif self.fOrientation == self.VERTICAL: painter.drawRect(meterX, int(value), self.fSizeMeter, self.fHeight) meterX += self.fSizeMeter if not self.fDrawLines: return painter.setBrush(Qt.black) if self.fOrientation == self.HORIZONTAL: # Variables lsmall = float(self.fWidth) lfull = float(self.fHeight - 1) # Base painter.setPen(self.fColorBaseAlt) painter.drawLine(lsmall * 0.25, 2, lsmall * 0.25, lfull-2.0) painter.drawLine(lsmall * 0.50, 2, lsmall * 0.50, lfull-2.0) # Yellow painter.setPen(QColor(110, 110, 15, 100)) painter.drawLine(lsmall * 0.70, 2, lsmall * 0.70, lfull-2.0) painter.drawLine(lsmall * 0.83, 2, lsmall * 0.83, lfull-2.0) # Orange painter.setPen(QColor(180, 110, 15, 100)) painter.drawLine(lsmall * 0.90, 2, lsmall * 0.90, lfull-2.0) # Red painter.setPen(QColor(110, 15, 15, 100)) painter.drawLine(lsmall * 0.96, 2, lsmall * 0.96, lfull-2.0) elif self.fOrientation == self.VERTICAL: # Variables lsmall = float(self.fHeight) lfull = float(self.fWidth - 1) # Base painter.setPen(self.fColorBaseAlt) painter.drawLine(2, lsmall - (lsmall * 0.25), lfull-2.0, lsmall - (lsmall * 0.25)) painter.drawLine(2, lsmall - (lsmall * 0.50), lfull-2.0, lsmall - (lsmall * 0.50)) # Yellow painter.setPen(QColor(110, 110, 15, 100)) painter.drawLine(2, lsmall - (lsmall * 0.70), lfull-2.0, lsmall - (lsmall * 0.70)) painter.drawLine(2, lsmall - (lsmall * 0.82), lfull-2.0, lsmall - (lsmall * 0.82)) # Orange painter.setPen(QColor(180, 110, 15, 100)) painter.drawLine(2, lsmall - (lsmall * 0.90), lfull-2.0, lsmall - (lsmall * 0.90)) # Red painter.setPen(QColor(110, 15, 15, 100)) painter.drawLine(2, lsmall - (lsmall * 0.96), lfull-2.0, lsmall - (lsmall * 0.96)) def resizeEvent(self, event): self.updateSizes() QWidget.resizeEvent(self, event)
class DLrcText(QLabel): qSizeChanged = pyqtSignal('QSize') hoverChanged = pyqtSignal(bool) def __init__(self, parent=None): super(DLrcText, self).__init__(parent) self.initData() self.initUI() self.initConnect() def initData(self): self._hovered = False self.linear_gradient = QLinearGradient() self.linear_gradient.setStart(0, 10) self.linear_gradient.setFinalStop(0, 40) self.linear_gradient.setColorAt(0.1, QColor(14, 179, 255)); self.linear_gradient.setColorAt(0.5, QColor(114, 232, 255)); self.linear_gradient.setColorAt(1, QColor(14, 179, 255)); self.mask_linear_gradient = QLinearGradient() self.mask_linear_gradient.setStart(0, 10) self.mask_linear_gradient.setFinalStop(0, 40) self.mask_linear_gradient.setColorAt(0.1, QColor(0, 100, 40)) self.mask_linear_gradient.setColorAt(0.5, QColor(0, 72, 16)) self.mask_linear_gradient.setColorAt(1, QColor(0, 255, 40)) self.text = "" self.percentage = 0 self.lyric_id = 0 self.line1_text = '' self.line1_percentage = 0 self.line2_text = '' self.line2_percentage = 0 self.lrcfont = QFont() self.lrcfont.setPixelSize(30) self.setFont(self.lrcfont) self._lineMode = 1 def initUI(self): pass def initConnect(self): signalManager.singleTextInfoChanged.connect(self.updateSingleText) signalManager.douleTextInfoChanged.connect(self.updateDoubleText) signalManager.noLrcFound.connect(self.updateNoLrcTip) signalManager.fontIncreaseChanged.connect(self.increaseFont) signalManager.fontDecreaseChanged.connect(self.decreaseFont) signalManager.showLrcSingleLine.connect(self.setSingleLine) signalManager.showLrcDoubleLine.connect(self.setDoubleLine) def disConnect(self): signalManager.singleTextInfoChanged.disconnect(self.updateSingleText) signalManager.douleTextInfoChanged.disconnect(self.updateDoubleText) signalManager.noLrcFound.disconnect(self.updateNoLrcTip) signalManager.fontIncreaseChanged.disconnect(self.increaseFont) signalManager.fontDecreaseChanged.disconnect(self.decreaseFont) signalManager.showLrcSingleLine.disconnect(self.setSingleLine) signalManager.showLrcDoubleLine.disconnect(self.setDoubleLine) def increaseFont(self): font = self.font() size = font.pixelSize() font.setPixelSize(size + 1) self.setFont(font) height = self.height() self.qSize = QSize(self.width(), height + 1) def decreaseFont(self): font = self.font() size = font.pixelSize() font.setPixelSize(size - 1) self.setFont(font) self.qSize = QSize(self.width(), self.height() - 1) def setSingleLine(self): if self._lineMode == 1: return self._lineMode = 1 self.qSize = QSize(self.width(), self.height() / 2) signalManager.lineModeChanged.emit(self._lineMode) def setDoubleLine(self): if self._lineMode == 2: return self._lineMode = 2 self.qSize = QSize(self.width(), self.height() * 2) signalManager.lineModeChanged.emit(self._lineMode) @pyqtProperty('QSize', notify=qSizeChanged) def qSize(self): return self.size() @qSize.setter def qSize(self, size): self.setFixedSize(size) self.qSizeChanged.emit(size) def setSize(self, size): self.qSize = size @pyqtProperty(bool, notify=hoverChanged) def hovered(self): return self._hovered @hovered.setter def hovered(self, hovered): self._hovered = hovered self.hoverChanged.emit(hovered) def setHovered(self, hovered): self.hovered = hovered def updateNoLrcTip(self): self.updateSingleText('No lyric found', 0, 0) def updateSingleText(self, text, percentage, lyric_id): self.text = text self.percentage = percentage self.lyric_id = lyric_id self.update() def updateDoubleText(self, texts): self.line1_text = texts[0][0] self.line1_percentage = texts[0][1] self.line2_text = texts[1][0] self.line2_percentage = texts[1][1] self.update() def updateTextSize(self, size): self.setFixedSize(size.width() - 100, self.height()) def paintEvent(self, event): painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) painter.setFont(self.font()) if self._lineMode == 1: self.drawText(painter, self.text, self.percentage) if self._lineMode == 2: self.drawText(painter, self.line1_text, self.line1_percentage, mode="Double", lineMode=1) self.drawText(painter, self.line2_text, self.line2_percentage, mode="Double", lineMode=2) super(DLrcText, self).paintEvent(event) def drawText(self, painter, text, percentage, mode='Single', lineMode=1): textWidth = self.fontMetrics().width(text) textHeight = self.fontMetrics().height() startX = 0 startY = 0 if mode == 'Single': startX = (self.width() - textWidth) / 2 startY = (self.height() - textHeight) / 2 elif mode == 'Double' and lineMode == 1: startX = (self.width() - textWidth) / 2 - self.width() / 4 startY = (self.height() / 2 - textHeight) / 2 elif mode == 'Double' and lineMode == 2: startX = (self.width() - textWidth) / 2 + self.width() / 4 startY = self.height() / 2 + (self.height() / 2 - textHeight) / 2 painter.setPen(QColor(0, 0, 0, 200)) painter.drawText(startX + 1, startY + 1, textWidth, textHeight, Qt.AlignLeft, text) painter.setPen(QPen(self.linear_gradient, 0)) painter.drawText(startX, startY, textWidth, textHeight, Qt.AlignLeft, text) self.mask_linear_gradient.setStart(startX, startY) self.mask_linear_gradient.setFinalStop(startX, startY + textHeight) painter.setPen(QPen(self.mask_linear_gradient, 0)) painter.drawText(startX, startY, textWidth * percentage , textHeight, Qt.AlignLeft, text)
def initChart(self): series = QLineSeries() data = [ QPoint(0, 4), QPoint(3, 2), QPoint(7, 7), QPoint(9, 10), QPoint(12, 17), QPoint(17, 9), QPoint(20, 22), QPoint(22, 2), QPoint(28, 13) ] series.append(data) # creating chart object chart = QChart() chart.legend().hide() chart.addSeries(series) pen = QPen(QColor(0, 0, 128)) pen.setWidth(3) series.setPen(pen) font = QFont("Open Sans") font.setPixelSize(40) font.setBold(True) chart.setTitleFont(font) chart.setTitleBrush(QBrush(Qt.yellow)) chart.setTitle("Custom Chart Demo") backgroundGradient = QLinearGradient() backgroundGradient.setStart(QPoint(0, 0)) backgroundGradient.setFinalStop(QPoint(0, 1)) backgroundGradient.setColorAt(0.0, QColor(175, 201, 182)) backgroundGradient.setColorAt(1.0, QColor(51, 105, 66)) backgroundGradient.setCoordinateMode(QGradient.ObjectBoundingMode) chart.setBackgroundBrush(backgroundGradient) plotAreaGraident = QLinearGradient() plotAreaGraident.setStart(QPoint(0, 1)) plotAreaGraident.setFinalStop(QPoint(1, 0)) plotAreaGraident.setColorAt(0.0, QColor(222, 222, 222)) plotAreaGraident.setColorAt(1.0, QColor(51, 105, 66)) plotAreaGraident.setCoordinateMode(QGradient.ObjectBoundingMode) chart.setPlotAreaBackgroundBrush(plotAreaGraident) chart.setPlotAreaBackgroundVisible(True) # customize axis axisX = QCategoryAxis() axisY = QCategoryAxis() labelFont = QFont("Open Sans") labelFont.setPixelSize(25) axisX.setLabelsFont(labelFont) axisY.setLabelsFont(labelFont) axisPen = QPen(Qt.white) axisPen.setWidth(2) axisX.setLinePen(axisPen) axisY.setLinePen(axisPen) axisBrush = QBrush(Qt.white) axisX.setLabelsBrush(axisBrush) axisY.setLabelsBrush(axisBrush) axisX.setRange(0, 30) axisX.append("low", 10) axisX.append("medium", 20) axisX.append("high", 30) axisY.setRange(0, 30) axisY.append("slow", 10) axisY.append("average", 20) axisY.append("fast", 30) axisX.setGridLineVisible(False) axisY.setGridLineVisible(False) chart.addAxis(axisX, Qt.AlignBottom) chart.addAxis(axisY, Qt.AlignLeft) series.attachAxis(axisX) series.attachAxis(axisY) self.chartView = QChartView(chart) self.chartView.setRenderHint(QPainter.Antialiasing)
class DigitalPeakMeter(QWidget): # enum Orientation HORIZONTAL = 1 VERTICAL = 2 # enum Color GREEN = 1 BLUE = 2 # enum Style STYLE_DEFAULT = 0 STYLE_OPENAV = 1 def __init__(self, parent): QWidget.__init__(self, parent) self.fChannels = 0 self.fDrawLines = True self.fOrientation = self.VERTICAL self.fSmoothMultiplier = 1 self.fColorBackground = QColor("#111111") self.fGradientMeter = QLinearGradient(0, 0, 1, 1) self.fMeterStyle = self.STYLE_DEFAULT self.setChannels(0) self.setColor(self.GREEN) def displayMeter(self, meter, level, forced = False): if meter <= 0 or meter > self.fChannels: return qCritical("DigitalPeakMeter::displayMeter(%i, %f) - invalid meter number" % (meter, level)) if not isinstance(level, float): return qCritical("DigitalPeakMeter::displayMeter(%i, %f) - meter value must be float" % (meter, level)) i = meter - 1 if self.fSmoothMultiplier > 0 and not forced: level = (self.fLastValueData[i] * self.fSmoothMultiplier + level) / float(self.fSmoothMultiplier + 1) if level < 0.001: level = 0.0 elif level > 0.999: level = 1.0 if self.fChannelsData[i] != level: self.fChannelsData[i] = level self.update() self.fLastValueData[i] = level def setChannels(self, channels): if channels < 0: return qCritical("DigitalPeakMeter::setChannels(%i) - 'channels' must be a positive integer" % channels) self.fChannels = channels self.fChannelsData = [] self.fLastValueData = [] for x in range(channels): self.fChannelsData.append(0.0) self.fLastValueData.append(0.0) def setColor(self, color): if color == self.GREEN: self.fColorBase = QColor(93, 231, 61) self.fColorBaseAlt = QColor(15, 110, 15, 100) elif color == self.BLUE: self.fColorBase = QColor(82, 238, 248) self.fColorBaseAlt = QColor(15, 15, 110, 100) else: return qCritical("DigitalPeakMeter::setColor(%i) - invalid color" % color) self.setOrientation(self.fOrientation) def setMeterStyle(self, style): self.fMeterStyle = style self.setOrientation(self.fOrientation) def setLinesEnabled(self, yesNo): self.fDrawLines = yesNo def setOrientation(self, orientation): self.fOrientation = orientation self.fGradientMeter = QLinearGradient(0, 0, 1, 1) if self.fMeterStyle == self.STYLE_OPENAV: self.fGradientMeter.setColorAt(0.0, self.fColorBase) self.fGradientMeter.setColorAt(1.0, self.fColorBase) elif self.fOrientation == self.HORIZONTAL: self.fGradientMeter.setColorAt(0.0, self.fColorBase) self.fGradientMeter.setColorAt(0.2, self.fColorBase) self.fGradientMeter.setColorAt(0.4, self.fColorBase) self.fGradientMeter.setColorAt(0.6, self.fColorBase) self.fGradientMeter.setColorAt(0.8, Qt.yellow) self.fGradientMeter.setColorAt(1.0, Qt.red) elif self.fOrientation == self.VERTICAL: self.fGradientMeter.setColorAt(0.0, Qt.red) self.fGradientMeter.setColorAt(0.2, Qt.yellow) self.fGradientMeter.setColorAt(0.4, self.fColorBase) self.fGradientMeter.setColorAt(0.6, self.fColorBase) self.fGradientMeter.setColorAt(0.8, self.fColorBase) self.fGradientMeter.setColorAt(1.0, self.fColorBase) else: return qCritical("DigitalPeakMeter::setOrientation(%i) - invalid orientation" % orientation) self.updateSizes() def setSmoothRelease(self, value): if value < 0: value = 0 elif value > 5: value = 5 self.fSmoothMultiplier = value def minimumSizeHint(self): return QSize(10, 10) def sizeHint(self): return QSize(self.fWidth, self.fHeight) def updateSizes(self): self.fWidth = self.width() self.fHeight = self.height() self.fSizeMeter = 0 if self.fOrientation == self.HORIZONTAL: self.fGradientMeter.setFinalStop(self.fWidth, 0) if self.fChannels > 0: self.fSizeMeter = self.fHeight / self.fChannels elif self.fOrientation == self.VERTICAL: self.fGradientMeter.setFinalStop(0, self.fHeight) if self.fChannels > 0: self.fSizeMeter = self.fWidth / self.fChannels def paintEvent(self, event): painter = QPainter(self) event.accept() if self.fMeterStyle == self.STYLE_OPENAV: painter.setPen(QColor("#1A1A1A")) painter.setBrush(QColor("#1A1A1A")) else: painter.setPen(Qt.black) painter.setBrush(Qt.black) painter.drawRect(0, 0, self.fWidth, self.fHeight) meterX = 0 startX = -1 if self.fMeterStyle == self.STYLE_OPENAV else 0 padding = 2 if self.fMeterStyle == self.STYLE_OPENAV else 0 painter.setPen(self.fColorBackground) painter.setBrush(self.fGradientMeter) if self.fMeterStyle == self.STYLE_OPENAV: color = self.fGradientMeter.stops()[0][1] painter.setPen(color) color.setAlphaF(0.5) painter.setBrush(color) del color for i in range(self.fChannels): level = self.fChannelsData[i] if self.fOrientation == self.HORIZONTAL: value = level * float(self.fWidth) elif self.fOrientation == self.VERTICAL: value = float(self.fHeight) - (level * float(self.fHeight)) else: value = 0.0 if self.fOrientation == self.HORIZONTAL: painter.drawRect(startX, meterX+padding, int(value), self.fSizeMeter-padding*(1 if self.fChannels > 1 else 2)) elif self.fOrientation == self.VERTICAL: painter.drawRect(meterX, int(value), self.fSizeMeter, self.fHeight) meterX += self.fSizeMeter if not self.fDrawLines: return painter.setBrush(Qt.black) if self.fOrientation == self.HORIZONTAL: # Variables lsmall = float(self.fWidth) lfull = float(self.fHeight - 1) if self.fMeterStyle == self.STYLE_OPENAV: painter.setPen(QColor(37, 37, 37, 100)) painter.drawLine(lsmall * 0.25, 2, lsmall * 0.25, lfull-2.0) painter.drawLine(lsmall * 0.50, 2, lsmall * 0.50, lfull-2.0) painter.drawLine(lsmall * 0.75, 2, lsmall * 0.75, lfull-2.0) if self.fChannels > 1: painter.drawLine(1, lfull/2, lsmall-1, lfull/2) else: # Base painter.setPen(self.fColorBaseAlt) painter.drawLine(lsmall * 0.25, 2, lsmall * 0.25, lfull-2.0) painter.drawLine(lsmall * 0.50, 2, lsmall * 0.50, lfull-2.0) # Yellow painter.setPen(QColor(110, 110, 15, 100)) painter.drawLine(lsmall * 0.70, 2, lsmall * 0.70, lfull-2.0) painter.drawLine(lsmall * 0.83, 2, lsmall * 0.83, lfull-2.0) # Orange painter.setPen(QColor(180, 110, 15, 100)) painter.drawLine(lsmall * 0.90, 2, lsmall * 0.90, lfull-2.0) # Red painter.setPen(QColor(110, 15, 15, 100)) painter.drawLine(lsmall * 0.96, 2, lsmall * 0.96, lfull-2.0) elif self.fOrientation == self.VERTICAL: # Variables lsmall = float(self.fHeight) lfull = float(self.fWidth - 1) if self.fMeterStyle == self.STYLE_OPENAV: # TODO pass else: # Base painter.setPen(self.fColorBaseAlt) painter.drawLine(2, lsmall - (lsmall * 0.25), lfull-2.0, lsmall - (lsmall * 0.25)) painter.drawLine(2, lsmall - (lsmall * 0.50), lfull-2.0, lsmall - (lsmall * 0.50)) # Yellow painter.setPen(QColor(110, 110, 15, 100)) painter.drawLine(2, lsmall - (lsmall * 0.70), lfull-2.0, lsmall - (lsmall * 0.70)) painter.drawLine(2, lsmall - (lsmall * 0.82), lfull-2.0, lsmall - (lsmall * 0.82)) # Orange painter.setPen(QColor(180, 110, 15, 100)) painter.drawLine(2, lsmall - (lsmall * 0.90), lfull-2.0, lsmall - (lsmall * 0.90)) # Red painter.setPen(QColor(110, 15, 15, 100)) painter.drawLine(2, lsmall - (lsmall * 0.96), lfull-2.0, lsmall - (lsmall * 0.96)) def resizeEvent(self, event): self.updateSizes() QWidget.resizeEvent(self, event)
class QDbMeter(QWidget): DB_MIN = int(config["DbMeter"]["dbMin"]) DB_MAX = int(config["DbMeter"]["dbMax"]) DB_CLIP = int(config["DbMeter"]["dbClip"]) def __init__(self, parent): super().__init__(parent) db_range = abs(self.DB_MIN - self.DB_MAX) yellow = abs(self.DB_MIN + 20) / db_range # -20 db red = abs(self.DB_MIN) / db_range # 0 db self.grad = QLinearGradient() self.grad.setColorAt(0, QColor(0, 255, 0)) # Green self.grad.setColorAt(yellow, QColor(255, 255, 0)) # Yellow self.grad.setColorAt(red, QColor(255, 0, 0)) # Red self.reset() def reset(self): self.peaks = [self.DB_MIN, self.DB_MIN] self.rmss = [self.DB_MIN, self.DB_MIN] self.decPeak = [self.DB_MIN, self.DB_MIN] self.clipping = {} self.repaint() def plot(self, peaks, rms, decPeak): self.peaks = peaks self.rmss = rms self.decPeak = decPeak self.repaint() @suppress_exceptions def paintEvent(self, e): if not self.visibleRegion().isEmpty(): # Stretch factor mul = (self.height() - 4) mul /= (self.DB_MAX - self.DB_MIN) peaks = [] for n, peak in enumerate(self.peaks): if peak > self.DB_CLIP: self.clipping[n] = True if peak < self.DB_MIN: peak = self.DB_MIN elif peak > self.DB_MAX: peak = self.DB_MAX peaks.append(round((peak - self.DB_MIN) * mul)) rmss = [] for n, rms in enumerate(self.rmss): if rms < self.DB_MIN: rms = self.DB_MIN elif rms > self.DB_MAX: rms = self.DB_MAX rmss.append(round((rms - self.DB_MIN) * mul)) dPeaks = [] for dPeak in self.decPeak: if dPeak < self.DB_MIN: dPeak = self.DB_MIN elif dPeak > self.DB_MAX: dPeak = self.DB_MAX dPeaks.append(round((dPeak - self.DB_MIN) * mul)) qp = QPainter() qp.begin(self) qp.setBrush(QColor(0, 0, 0, 0)) xpos = 0 xdim = self.width() / len(peaks) for n, (peak, rms, dPeak) in enumerate(zip(peaks, rmss, dPeaks)): # Maximum "peak-rect" size maxRect = QtCore.QRect(xpos, self.height() - 2, xdim - 2, 2 - self.height()) # Set QLinearGradient start and final-stop position self.grad.setStart(maxRect.topLeft()) self.grad.setFinalStop(maxRect.bottomRight()) # Draw peak (audio peak in dB) rect = QtCore.QRect(xpos, self.height() - 2, xdim - 2, -peak) qp.setOpacity(0.6) qp.fillRect(rect, self.grad) qp.setOpacity(1.0) # Draw rms (in db) rect = QtCore.QRect(xpos, self.height() - 2, xdim - 2, -rms) qp.fillRect(rect, self.grad) # Draw decay peak decRect = QtCore.QRect(xpos, (self.height() - 3) - dPeak, xdim - 2, 2) qp.fillRect(decRect, self.grad) # Draw Borders if self.clipping.get(n, False): qp.setPen(QColor(200, 0, 0)) else: qp.setPen(QColor(100, 100, 100)) qp.drawRect(maxRect) xpos += xdim qp.end()
class DLrcText(QLabel): qSizeChanged = pyqtSignal('QSize') hoverChanged = pyqtSignal(bool) def __init__(self, parent=None): super(DLrcText, self).__init__(parent) self.initData() self.initUI() self.initConnect() def initData(self): self._hovered = False self.linear_gradient = QLinearGradient() self.linear_gradient.setStart(0, 10) self.linear_gradient.setFinalStop(0, 40) self.linear_gradient.setColorAt(0.1, QColor(14, 179, 255)) self.linear_gradient.setColorAt(0.5, QColor(114, 232, 255)) self.linear_gradient.setColorAt(1, QColor(14, 179, 255)) self.mask_linear_gradient = QLinearGradient() self.mask_linear_gradient.setStart(0, 10) self.mask_linear_gradient.setFinalStop(0, 40) self.mask_linear_gradient.setColorAt(0.1, QColor(0, 100, 40)) self.mask_linear_gradient.setColorAt(0.5, QColor(0, 72, 16)) self.mask_linear_gradient.setColorAt(1, QColor(0, 255, 40)) self.text = "" self.percentage = 0 self.lyric_id = 0 self.line1_text = '' self.line1_percentage = 0 self.line2_text = '' self.line2_percentage = 0 self.lrcfont = QFont() self.lrcfont.setPixelSize(30) self.setFont(self.lrcfont) self._lineMode = 1 def initUI(self): pass def initConnect(self): signalManager.singleTextInfoChanged.connect(self.updateSingleText) signalManager.douleTextInfoChanged.connect(self.updateDoubleText) signalManager.noLrcFound.connect(self.updateNoLrcTip) signalManager.fontIncreaseChanged.connect(self.increaseFont) signalManager.fontDecreaseChanged.connect(self.decreaseFont) signalManager.showLrcSingleLine.connect(self.setSingleLine) signalManager.showLrcDoubleLine.connect(self.setDoubleLine) def disConnect(self): signalManager.singleTextInfoChanged.disconnect(self.updateSingleText) signalManager.douleTextInfoChanged.disconnect(self.updateDoubleText) signalManager.noLrcFound.disconnect(self.updateNoLrcTip) signalManager.fontIncreaseChanged.disconnect(self.increaseFont) signalManager.fontDecreaseChanged.disconnect(self.decreaseFont) signalManager.showLrcSingleLine.disconnect(self.setSingleLine) signalManager.showLrcDoubleLine.disconnect(self.setDoubleLine) def increaseFont(self): font = self.font() size = font.pixelSize() font.setPixelSize(size + 1) self.setFont(font) height = self.height() self.qSize = QSize(self.width(), height + 1) def decreaseFont(self): font = self.font() size = font.pixelSize() font.setPixelSize(size - 1) self.setFont(font) self.qSize = QSize(self.width(), self.height() - 1) def setSingleLine(self): if self._lineMode == 1: return self._lineMode = 1 self.qSize = QSize(self.width(), self.height() / 2) signalManager.lineModeChanged.emit(self._lineMode) def setDoubleLine(self): if self._lineMode == 2: return self._lineMode = 2 self.qSize = QSize(self.width(), self.height() * 2) signalManager.lineModeChanged.emit(self._lineMode) @pyqtProperty('QSize', notify=qSizeChanged) def qSize(self): return self.size() @qSize.setter def qSize(self, size): self.setFixedSize(size) self.qSizeChanged.emit(size) def setSize(self, size): self.qSize = size @pyqtProperty(bool, notify=hoverChanged) def hovered(self): return self._hovered @hovered.setter def hovered(self, hovered): self._hovered = hovered self.hoverChanged.emit(hovered) def setHovered(self, hovered): self.hovered = hovered def updateNoLrcTip(self): self.updateSingleText('No lyric found', 0, 0) def updateSingleText(self, text, percentage, lyric_id): self.text = text self.percentage = percentage self.lyric_id = lyric_id self.update() def updateDoubleText(self, texts): self.line1_text = texts[0][0] self.line1_percentage = texts[0][1] self.line2_text = texts[1][0] self.line2_percentage = texts[1][1] self.update() def updateTextSize(self, size): self.setFixedSize(size.width() - 100, self.height()) def paintEvent(self, event): painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) painter.setFont(self.font()) if self._lineMode == 1: self.drawText(painter, self.text, self.percentage) if self._lineMode == 2: self.drawText(painter, self.line1_text, self.line1_percentage, mode="Double", lineMode=1) self.drawText(painter, self.line2_text, self.line2_percentage, mode="Double", lineMode=2) super(DLrcText, self).paintEvent(event) def drawText(self, painter, text, percentage, mode='Single', lineMode=1): textWidth = self.fontMetrics().width(text) textHeight = self.fontMetrics().height() startX = 0 startY = 0 if mode == 'Single': startX = (self.width() - textWidth) / 2 startY = (self.height() - textHeight) / 2 elif mode == 'Double' and lineMode == 1: startX = (self.width() - textWidth) / 2 - self.width() / 4 startY = (self.height() / 2 - textHeight) / 2 elif mode == 'Double' and lineMode == 2: startX = (self.width() - textWidth) / 2 + self.width() / 4 startY = self.height() / 2 + (self.height() / 2 - textHeight) / 2 painter.setPen(QColor(0, 0, 0, 200)) painter.drawText(startX + 1, startY + 1, textWidth, textHeight, Qt.AlignLeft, text) painter.setPen(QPen(self.linear_gradient, 0)) painter.drawText(startX, startY, textWidth, textHeight, Qt.AlignLeft, text) self.mask_linear_gradient.setStart(startX, startY) self.mask_linear_gradient.setFinalStop(startX, startY + textHeight) painter.setPen(QPen(self.mask_linear_gradient, 0)) painter.drawText(startX, startY, textWidth * percentage, textHeight, Qt.AlignLeft, text)
class DigitalPeakMeter(QWidget): # enum Color COLOR_GREEN = 1 COLOR_BLUE = 2 # enum Orientation HORIZONTAL = 1 VERTICAL = 2 # enum Style STYLE_DEFAULT = 1 STYLE_OPENAV = 2 STYLE_RNCBC = 3 STYLE_CALF = 4 # -------------------------------------------------------------------------------------------------------- def __init__(self, parent): QWidget.__init__(self, parent) self.setAttribute(Qt.WA_OpaquePaintEvent) # defaults are VERTICAL, COLOR_GREEN, STYLE_DEFAULT self.fChannelCount = 0 self.fChannelData = [] self.fLastChannelData = [] self.fMeterColor = self.COLOR_GREEN self.fMeterColorBase = QColor(93, 231, 61) self.fMeterColorBaseAlt = QColor(15, 110, 15, 100) self.fMeterLinesEnabled = True self.fMeterOrientation = self.VERTICAL self.fMeterStyle = self.STYLE_DEFAULT self.fMeterBackground = QColor("#070707") self.fMeterGradient = QLinearGradient(0, 0, 0, 0) self.fMeterPixmaps = () self.fSmoothMultiplier = 2 self.updateGrandient() # -------------------------------------------------------------------------------------------------------- def channelCount(self): return self.fChannelCount def setChannelCount(self, count): if self.fChannelCount == count: return if count < 0: return qCritical( "DigitalPeakMeter::setChannelCount(%i) - channel count must be a positive integer or zero" % count) self.fChannelCount = count self.fChannelData = [] self.fLastChannelData = [] for x in range(count): self.fChannelData.append(0.0) self.fLastChannelData.append(0.0) if self.fMeterStyle == self.STYLE_CALF: if self.fChannelCount > 0: self.setFixedSize(100, 12 * self.fChannelCount) else: self.setMinimumSize(0, 0) self.setMaximumSize(9999, 9999) # -------------------------------------------------------------------------------------------------------- def meterColor(self): return self.fMeterColor def setMeterColor(self, color): if self.fMeterColor == color: return if color not in (self.COLOR_GREEN, self.COLOR_BLUE): return qCritical( "DigitalPeakMeter::setMeterColor(%i) - invalid color" % color) if color == self.COLOR_GREEN: self.fMeterColorBase = QColor(93, 231, 61) self.fMeterColorBaseAlt = QColor(15, 110, 15, 100) elif color == self.COLOR_BLUE: self.fMeterColorBase = QColor(82, 238, 248) self.fMeterColorBaseAlt = QColor(15, 15, 110, 100) self.fMeterColor = color self.updateGrandient() # -------------------------------------------------------------------------------------------------------- def meterLinesEnabled(self): return self.fMeterLinesEnabled def setMeterLinesEnabled(self, yesNo): if self.fMeterLinesEnabled == yesNo: return self.fMeterLinesEnabled = yesNo # -------------------------------------------------------------------------------------------------------- def meterOrientation(self): return self.fMeterOrientation def setMeterOrientation(self, orientation): if self.fMeterOrientation == orientation: return if orientation not in (self.HORIZONTAL, self.VERTICAL): return qCritical( "DigitalPeakMeter::setMeterOrientation(%i) - invalid orientation" % orientation) self.fMeterOrientation = orientation self.updateGrandient() # -------------------------------------------------------------------------------------------------------- def meterStyle(self): return self.fMeterStyle def setMeterStyle(self, style): if self.fMeterStyle == style: return if style not in (self.STYLE_DEFAULT, self.STYLE_OPENAV, self.STYLE_RNCBC, self.STYLE_CALF): return qCritical( "DigitalPeakMeter::setMeterStyle(%i) - invalid style" % style) if style == self.STYLE_DEFAULT: self.fMeterBackground = QColor("#070707") elif style == self.STYLE_OPENAV: self.fMeterBackground = QColor("#1A1A1A") elif style == self.STYLE_RNCBC: self.fMeterBackground = QColor("#070707") elif style == self.STYLE_CALF: self.fMeterBackground = QColor("#000") if style == self.STYLE_CALF: self.fMeterPixmaps = (QPixmap(":/bitmaps/meter_calf_off.png"), QPixmap(":/bitmaps/meter_calf_on.png")) if self.fChannelCount > 0: self.setFixedSize(100, 12 * self.fChannelCount) else: self.fMeterPixmaps = () self.setMinimumSize(0, 0) self.setMaximumSize(9999, 9999) self.fMeterStyle = style self.updateGrandient() # -------------------------------------------------------------------------------------------------------- def smoothMultiplier(self): return self.fSmoothMultiplier def setSmoothMultiplier(self, value): if self.fSmoothMultiplier == value: return if not isinstance(value, int): return qCritical( "DigitalPeakMeter::setSmoothMultiplier() - value must be an integer" ) if value < 0: return qCritical( "DigitalPeakMeter::setSmoothMultiplier(%i) - value must be >= 0" % value) if value > 5: return qCritical( "DigitalPeakMeter::setSmoothMultiplier(%i) - value must be < 5" % value) self.fSmoothMultiplier = value # -------------------------------------------------------------------------------------------------------- def displayMeter(self, meter, level, forced=False): if not isinstance(meter, int): return qCritical( "DigitalPeakMeter::displayMeter(,) - meter value must be an integer" ) if not isinstance(level, float): return qCritical( "DigitalPeakMeter::displayMeter(%i,) - level value must be a float" % (meter, )) if meter <= 0 or meter > self.fChannelCount: return qCritical( "DigitalPeakMeter::displayMeter(%i, %f) - invalid meter number" % (meter, level)) i = meter - 1 if self.fSmoothMultiplier > 0 and not forced: level = (self.fLastChannelData[i] * float(self.fSmoothMultiplier) + level) / float(self.fSmoothMultiplier + 1) if level < 0.001: level = 0.0 elif level > 0.999: level = 1.0 if self.fChannelData[i] != level: self.fChannelData[i] = level self.update() self.fLastChannelData[i] = level # -------------------------------------------------------------------------------------------------------- def updateGrandient(self): self.fMeterGradient = QLinearGradient(0, 0, 1, 1) if self.fMeterStyle == self.STYLE_DEFAULT: if self.fMeterOrientation == self.HORIZONTAL: self.fMeterGradient.setColorAt(0.0, self.fMeterColorBase) self.fMeterGradient.setColorAt(0.2, self.fMeterColorBase) self.fMeterGradient.setColorAt(0.4, self.fMeterColorBase) self.fMeterGradient.setColorAt(0.6, self.fMeterColorBase) self.fMeterGradient.setColorAt(0.8, Qt.yellow) self.fMeterGradient.setColorAt(1.0, Qt.red) elif self.fMeterOrientation == self.VERTICAL: self.fMeterGradient.setColorAt(0.0, Qt.red) self.fMeterGradient.setColorAt(0.2, Qt.yellow) self.fMeterGradient.setColorAt(0.4, self.fMeterColorBase) self.fMeterGradient.setColorAt(0.6, self.fMeterColorBase) self.fMeterGradient.setColorAt(0.8, self.fMeterColorBase) self.fMeterGradient.setColorAt(1.0, self.fMeterColorBase) elif self.fMeterStyle == self.STYLE_RNCBC: if self.fMeterColor == self.COLOR_BLUE: c1 = QColor(40, 160, 160) c2 = QColor(60, 220, 160) elif self.fMeterColor == self.COLOR_GREEN: c1 = QColor(40, 160, 40) c2 = QColor(160, 220, 20) if self.fMeterOrientation == self.HORIZONTAL: self.fMeterGradient.setColorAt(0.0, c1) self.fMeterGradient.setColorAt(0.2, c1) self.fMeterGradient.setColorAt(0.6, c2) self.fMeterGradient.setColorAt(0.7, QColor(220, 220, 20)) self.fMeterGradient.setColorAt(0.8, QColor(240, 160, 20)) self.fMeterGradient.setColorAt(0.9, QColor(240, 0, 20)) self.fMeterGradient.setColorAt(1.0, QColor(240, 0, 20)) elif self.fMeterOrientation == self.VERTICAL: self.fMeterGradient.setColorAt(0.0, QColor(240, 0, 20)) self.fMeterGradient.setColorAt(0.1, QColor(240, 0, 20)) self.fMeterGradient.setColorAt(0.2, QColor(240, 160, 20)) self.fMeterGradient.setColorAt(0.3, QColor(220, 220, 20)) self.fMeterGradient.setColorAt(0.4, c2) self.fMeterGradient.setColorAt(0.8, c1) self.fMeterGradient.setColorAt(1.0, c1) elif self.fMeterStyle in (self.STYLE_OPENAV, self.STYLE_CALF): self.fMeterGradient.setColorAt(0.0, self.fMeterColorBase) self.fMeterGradient.setColorAt(1.0, self.fMeterColorBase) self.updateGrandientFinalStop() def updateGrandientFinalStop(self): if self.fMeterOrientation == self.HORIZONTAL: self.fMeterGradient.setFinalStop(self.width(), 0) elif self.fMeterOrientation == self.VERTICAL: self.fMeterGradient.setFinalStop(0, self.height()) # -------------------------------------------------------------------------------------------------------- def minimumSizeHint(self): return QSize(10, 10) def sizeHint(self): return QSize(self.width(), self.height()) # -------------------------------------------------------------------------------------------------------- def drawCalf(self, event): painter = QPainter(self) event.accept() # no channels, draw black if self.fChannelCount == 0: painter.setPen(QPen(Qt.black, 2)) painter.setBrush(Qt.black) painter.drawRect(0, 0, self.width(), self.height()) return for i in range(self.fChannelCount): painter.drawPixmap(0, 12 * i, self.fMeterPixmaps[0]) meterPos = 4 meterSize = 12 # draw levels for level in self.fChannelData: if level != 0.0: blevel = int(sqrt(level) * 26.0) * 3 painter.drawPixmap(5, meterPos, blevel, 4, self.fMeterPixmaps[1], 0, 0, blevel, 4) meterPos += meterSize def paintEvent(self, event): if self.fMeterStyle == self.STYLE_CALF: return self.drawCalf(event) painter = QPainter(self) event.accept() width = self.width() height = self.height() # draw background painter.setPen(QPen(self.fMeterBackground, 2)) painter.setBrush(self.fMeterBackground) painter.drawRect(0, 0, width, height) if self.fChannelCount == 0: return meterPad = 0 meterPos = 0 meterSize = (height if self.fMeterOrientation == self.HORIZONTAL else width) / self.fChannelCount # set pen/brush for levels if self.fMeterStyle == self.STYLE_OPENAV: colorTrans = QColor(self.fMeterColorBase) colorTrans.setAlphaF(0.5) painter.setBrush(colorTrans) painter.setPen(QPen(self.fMeterColorBase, 1)) del colorTrans meterPad += 2 meterSize -= 2 else: painter.setPen(QPen(self.fMeterBackground, 0)) painter.setBrush(self.fMeterGradient) # draw levels for level in self.fChannelData: if level == 0.0: pass elif self.fMeterOrientation == self.HORIZONTAL: painter.drawRect(0, meterPos, int(sqrt(level) * float(width)), meterSize) elif self.fMeterOrientation == self.VERTICAL: painter.drawRect(meterPos, height - int(sqrt(level) * float(height)), meterSize, height) meterPos += meterSize + meterPad if not self.fMeterLinesEnabled: return # draw lines if self.fMeterOrientation == self.HORIZONTAL: # Variables lsmall = float(width) lfull = float(height - 1) if self.fMeterStyle == self.STYLE_OPENAV: painter.setPen(QColor(37, 37, 37, 100)) painter.drawLine(lsmall * 0.25, 2, lsmall * 0.25, lfull - 2.0) painter.drawLine(lsmall * 0.50, 2, lsmall * 0.50, lfull - 2.0) painter.drawLine(lsmall * 0.75, 2, lsmall * 0.75, lfull - 2.0) if self.fChannelCount > 1: painter.drawLine(1, lfull / 2 - 1, lsmall - 1, lfull / 2 - 1) else: # Base painter.setBrush(Qt.black) painter.setPen(QPen(self.fMeterColorBaseAlt, 1)) painter.drawLine(lsmall * 0.25, 2, lsmall * 0.25, lfull - 2.0) painter.drawLine(lsmall * 0.50, 2, lsmall * 0.50, lfull - 2.0) # Yellow painter.setPen(QColor(110, 110, 15, 100)) painter.drawLine(lsmall * 0.70, 2, lsmall * 0.70, lfull - 2.0) painter.drawLine(lsmall * 0.83, 2, lsmall * 0.83, lfull - 2.0) # Orange painter.setPen(QColor(180, 110, 15, 100)) painter.drawLine(lsmall * 0.90, 2, lsmall * 0.90, lfull - 2.0) # Red painter.setPen(QColor(110, 15, 15, 100)) painter.drawLine(lsmall * 0.96, 2, lsmall * 0.96, lfull - 2.0) elif self.fMeterOrientation == self.VERTICAL: # Variables lsmall = float(height) lfull = float(width - 1) if self.fMeterStyle == self.STYLE_OPENAV: painter.setPen(QColor(37, 37, 37, 100)) painter.drawLine(2, lsmall - (lsmall * 0.25), lfull - 2.0, lsmall - (lsmall * 0.25)) painter.drawLine(2, lsmall - (lsmall * 0.50), lfull - 2.0, lsmall - (lsmall * 0.50)) painter.drawLine(2, lsmall - (lsmall * 0.75), lfull - 2.0, lsmall - (lsmall * 0.75)) if self.fChannelCount > 1: painter.drawLine(lfull / 2 - 1, 1, lfull / 2 - 1, lsmall - 1) else: # Base painter.setBrush(Qt.black) painter.setPen(QPen(self.fMeterColorBaseAlt, 1)) painter.drawLine(2, lsmall - (lsmall * 0.25), lfull - 2.0, lsmall - (lsmall * 0.25)) painter.drawLine(2, lsmall - (lsmall * 0.50), lfull - 2.0, lsmall - (lsmall * 0.50)) # Yellow painter.setPen(QColor(110, 110, 15, 100)) painter.drawLine(2, lsmall - (lsmall * 0.70), lfull - 2.0, lsmall - (lsmall * 0.70)) painter.drawLine(2, lsmall - (lsmall * 0.82), lfull - 2.0, lsmall - (lsmall * 0.82)) # Orange painter.setPen(QColor(180, 110, 15, 100)) painter.drawLine(2, lsmall - (lsmall * 0.90), lfull - 2.0, lsmall - (lsmall * 0.90)) # Red painter.setPen(QColor(110, 15, 15, 100)) painter.drawLine(2, lsmall - (lsmall * 0.96), lfull - 2.0, lsmall - (lsmall * 0.96)) # -------------------------------------------------------------------------------------------------------- def resizeEvent(self, event): QWidget.resizeEvent(self, event) self.updateGrandientFinalStop()
class QSlideSwitchPrivate(QObject): def __init__(self, q): QObject.__init__(self) self._position = 0 self._sliderShape = QRectF() self._gradient = QLinearGradient() self._gradient.setSpread(QGradient.PadSpread) self._qPointer = q self.animation = QPropertyAnimation(self, b"position") self.animation.setTargetObject(self) # self.animation.setPropertyName() self.animation.setStartValue(0) self.animation.setEndValue(1) self.animation.setDuration(300) self.animation.setEasingCurve(QEasingCurve.InOutExpo) def __del__(self): del self.animation @pyqtProperty(float) def position(self): return self._position @position.setter def position(self, value): self._position = value self._qPointer.repaint() def drawSlider(self, painter): margin = 3 r = self._qPointer.rect().adjusted(0, 0, -1, -1) dx = (r.width() - self._sliderShape.width()) * self._position sliderRect = self._sliderShape.translated(dx, 0) painter.setPen(Qt.NoPen) # basic settings shadow = self._qPointer.palette().color(QPalette.Dark) light = self._qPointer.palette().color(QPalette.Light) button = self._qPointer.palette().color(QPalette.Button) # draw background # draw outer background self._gradient.setColorAt(0, shadow.darker(130)) self._gradient.setColorAt(1, light.darker(130)) self._gradient.setStart(0, r.height()) self._gradient.setFinalStop(0, 0) painter.setBrush(self._gradient) painter.drawRoundedRect(r, 15, 15) # draw background # draw inner background self._gradient.setColorAt(0, shadow.darker(140)) self._gradient.setColorAt(1, light.darker(160)) self._gradient.setStart(0, 0) self._gradient.setFinalStop(0, r.height()) painter.setBrush(self._gradient) painter.drawRoundedRect(r.adjusted(margin, margin, -margin, -margin), 15, 15) # draw slider self._gradient.setColorAt(0, button.darker(130)) self._gradient.setColorAt(1, button) # draw outer slider self._gradient.setStart(0, r.height()) self._gradient.setFinalStop(0, 0) painter.setBrush(self._gradient) painter.drawRoundedRect(sliderRect.adjusted(margin, margin, -margin, -margin), 10, 15) # draw inner slider self._gradient.setStart(0, 0) self._gradient.setFinalStop(0, r.height()) painter.setBrush(self._gradient) painter.drawRoundedRect(sliderRect.adjusted(2.5 * margin, 2.5 * margin, -2.5 * margin, - 2.5 * margin), 5, 15) # draw text if self.animation.state() == QPropertyAnimation.Running: return # don't draw any text while animation is running font = self._qPointer.font() self._gradient.setColorAt(0, light) self._gradient.setColorAt(1, shadow) self._gradient.setStart(0, r.height() / 2.0 + font.pointSizeF()) self._gradient.setFinalStop(0, r.height() / 2.0 - font.pointSizeF()) painter.setFont(font) painter.setPen(QPen(QBrush(self._gradient), 0)) if self._qPointer.isChecked(): painter.drawText(0, 0, r.width() / 2, r.height() - 1, Qt.AlignCenter, "ON") else: painter.drawText(r.width() / 2, 0, r.width() / 2, r.height() - 1, Qt.AlignCenter, "OFF") def updateSliderRect(self, size): self._sliderShape.setWidth(size.width() / 2.0) self._sliderShape.setHeight(size.height() - 1.0) @pyqtSlot(bool, name='animate') def animate(self, checked): self.animation.setDirection(QPropertyAnimation.Forward if checked else QPropertyAnimation.Backward) self.animation.start()
class ScalableDial(QDial): # enum CustomPaintMode CUSTOM_PAINT_MODE_NULL = 0 # default (NOTE: only this mode has label gradient) CUSTOM_PAINT_MODE_CARLA_WET = 1 # color blue-green gradient (reserved #3) CUSTOM_PAINT_MODE_CARLA_VOL = 2 # color blue (reserved #3) CUSTOM_PAINT_MODE_CARLA_L = 3 # color yellow (reserved #4) CUSTOM_PAINT_MODE_CARLA_R = 4 # color yellow (reserved #4) CUSTOM_PAINT_MODE_CARLA_PAN = 5 # color yellow (reserved #3) CUSTOM_PAINT_MODE_COLOR = 6 # color, selectable (reserved #3) CUSTOM_PAINT_MODE_ZITA = 7 # custom zita knob (reserved #6) CUSTOM_PAINT_MODE_NO_GRADIENT = 8 # skip label gradient # enum Orientation HORIZONTAL = 0 VERTICAL = 1 HOVER_MIN = 0 HOVER_MAX = 9 MODE_DEFAULT = 0 MODE_LINEAR = 1 # signals dragStateChanged = pyqtSignal(bool) realValueChanged = pyqtSignal(float) def __init__(self, parent, index=0): QDial.__init__(self, parent) self.fDialMode = self.MODE_LINEAR self.fMinimum = 0.0 self.fMaximum = 1.0 self.fRealValue = 0.0 self.fPrecision = 10000 self.fIsInteger = False self.fIsHovered = False self.fIsPressed = False self.fHoverStep = self.HOVER_MIN self.fLastDragPos = None self.fLastDragValue = 0.0 self.fIndex = index self.fImage = QSvgWidget(":/scalable/dial_03.svg") self.fImageNum = "01" if self.fImage.sizeHint().width() > self.fImage.sizeHint().height(): self.fImageOrientation = self.HORIZONTAL else: self.fImageOrientation = self.VERTICAL self.fLabel = "" self.fLabelPos = QPointF(0.0, 0.0) self.fLabelFont = QFont(self.font()) self.fLabelFont.setPixelSize(8) self.fLabelWidth = 0 self.fLabelHeight = 0 if self.palette().window().color().lightness() > 100: # Light background c = self.palette().dark().color() self.fLabelGradientColor1 = c self.fLabelGradientColor2 = QColor(c.red(), c.green(), c.blue(), 0) self.fLabelGradientColorT = [ self.palette().buttonText().color(), self.palette().mid().color() ] else: # Dark background self.fLabelGradientColor1 = QColor(0, 0, 0, 255) self.fLabelGradientColor2 = QColor(0, 0, 0, 0) self.fLabelGradientColorT = [Qt.white, Qt.darkGray] self.fLabelGradient = QLinearGradient(0, 0, 0, 1) self.fLabelGradient.setColorAt(0.0, self.fLabelGradientColor1) self.fLabelGradient.setColorAt(0.6, self.fLabelGradientColor1) self.fLabelGradient.setColorAt(1.0, self.fLabelGradientColor2) self.fLabelGradientRect = QRectF(0.0, 0.0, 0.0, 0.0) self.fCustomPaintMode = self.CUSTOM_PAINT_MODE_NULL self.fCustomPaintColor = QColor(0xff, 0xff, 0xff) self.updateSizes() # Fake internal value, custom precision QDial.setMinimum(self, 0) QDial.setMaximum(self, self.fPrecision) QDial.setValue(self, 0) self.valueChanged.connect(self.slot_valueChanged) def getIndex(self): return self.fIndex def getBaseSize(self): return self.fImageBaseSize def forceWhiteLabelGradientText(self): self.fLabelGradientColor1 = QColor(0, 0, 0, 255) self.fLabelGradientColor2 = QColor(0, 0, 0, 0) self.fLabelGradientColorT = [Qt.white, Qt.darkGray] def setLabelColor(self, enabled, disabled): self.fLabelGradientColor1 = QColor(0, 0, 0, 255) self.fLabelGradientColor2 = QColor(0, 0, 0, 0) self.fLabelGradientColorT = [enabled, disabled] def updateSizes(self): if isinstance(self.fImage, QPixmap): self.fImageWidth = self.fImage.width() self.fImageHeight = self.fImage.height() else: self.fImageWidth = self.fImage.sizeHint().width() self.fImageHeight = self.fImage.sizeHint().height() if self.fImageWidth < 1: self.fImageWidth = 1 if self.fImageHeight < 1: self.fImageHeight = 1 if self.fImageOrientation == self.HORIZONTAL: self.fImageBaseSize = self.fImageHeight self.fImageLayersCount = self.fImageWidth / self.fImageHeight else: self.fImageBaseSize = self.fImageWidth self.fImageLayersCount = self.fImageHeight / self.fImageWidth self.setMinimumSize(self.fImageBaseSize, self.fImageBaseSize + self.fLabelHeight + 5) self.setMaximumSize(self.fImageBaseSize, self.fImageBaseSize + self.fLabelHeight + 5) if not self.fLabel: self.fLabelHeight = 0 self.fLabelWidth = 0 return self.fLabelWidth = QFontMetrics(self.fLabelFont).width(self.fLabel) self.fLabelHeight = QFontMetrics(self.fLabelFont).height() self.fLabelPos.setX( float(self.fImageBaseSize) / 2.0 - float(self.fLabelWidth) / 2.0) if self.fImageNum in ("01", "02", "07", "08", "09", "10"): self.fLabelPos.setY(self.fImageBaseSize + self.fLabelHeight) elif self.fImageNum in ("11", ): self.fLabelPos.setY(self.fImageBaseSize + self.fLabelHeight * 2 / 3) else: self.fLabelPos.setY(self.fImageBaseSize + self.fLabelHeight / 2) self.fLabelGradient.setStart(0, float(self.fImageBaseSize) / 2.0) self.fLabelGradient.setFinalStop( 0, self.fImageBaseSize + self.fLabelHeight + 5) self.fLabelGradientRect = QRectF( float(self.fImageBaseSize) / 8.0, float(self.fImageBaseSize) / 2.0, float(self.fImageBaseSize * 3) / 4.0, self.fImageBaseSize + self.fLabelHeight + 5) def setCustomPaintMode(self, paintMode): if self.fCustomPaintMode == paintMode: return self.fCustomPaintMode = paintMode self.update() def setCustomPaintColor(self, color): if self.fCustomPaintColor == color: return self.fCustomPaintColor = color self.update() def setLabel(self, label): if self.fLabel == label: return self.fLabel = label self.updateSizes() self.update() def setIndex(self, index): self.fIndex = index def setImage(self, imageId): self.fImageNum = "%02i" % imageId if imageId in (2, 6, 7, 8, 9, 10, 11, 12, 13): img = ":/bitmaps/dial_%s%s.png" % (self.fImageNum, "" if self.isEnabled() else "d") else: img = ":/scalable/dial_%s%s.svg" % (self.fImageNum, "" if self.isEnabled() else "d") if img.endswith(".png"): if not isinstance(self.fImage, QPixmap): self.fImage = QPixmap() else: if not isinstance(self.fImage, QSvgWidget): self.fImage = QSvgWidget() self.fImage.load(img) if self.fImage.width() > self.fImage.height(): self.fImageOrientation = self.HORIZONTAL else: self.fImageOrientation = self.VERTICAL # special svgs if self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_NULL: # reserved for carla-wet, carla-vol, carla-pan and color if self.fImageNum == "03": self.fCustomPaintMode = self.CUSTOM_PAINT_MODE_COLOR # reserved for carla-L and carla-R elif self.fImageNum == "04": self.fCustomPaintMode = self.CUSTOM_PAINT_MODE_CARLA_L # reserved for zita elif self.fImageNum == "06": self.fCustomPaintMode = self.CUSTOM_PAINT_MODE_ZITA self.updateSizes() self.update() def setPrecision(self, value, isInteger): self.fPrecision = value self.fIsInteger = isInteger QDial.setMaximum(self, value) def setMinimum(self, value): self.fMinimum = value def setMaximum(self, value): self.fMaximum = value def rvalue(self): return self.fRealValue def setValue(self, value, emitSignal=False): if self.fRealValue == value or isnan(value): return if value <= self.fMinimum: qtValue = 0 self.fRealValue = self.fMinimum elif value >= self.fMaximum: qtValue = self.fPrecision self.fRealValue = self.fMaximum else: qtValue = round( float(value - self.fMinimum) / float(self.fMaximum - self.fMinimum) * self.fPrecision) self.fRealValue = value # Block change signal, we'll handle it ourselves self.blockSignals(True) QDial.setValue(self, qtValue) self.blockSignals(False) if emitSignal: self.realValueChanged.emit(self.fRealValue) @pyqtSlot(int) def slot_valueChanged(self, value): self.fRealValue = float(value) / self.fPrecision * ( self.fMaximum - self.fMinimum) + self.fMinimum self.realValueChanged.emit(self.fRealValue) @pyqtSlot() def slot_updateImage(self): self.setImage(int(self.fImageNum)) def minimumSizeHint(self): return QSize(self.fImageBaseSize, self.fImageBaseSize) def sizeHint(self): return QSize(self.fImageBaseSize, self.fImageBaseSize) def changeEvent(self, event): QDial.changeEvent(self, event) # Force svg update if enabled state changes if event.type() == QEvent.EnabledChange: self.slot_updateImage() def enterEvent(self, event): self.fIsHovered = True if self.fHoverStep == self.HOVER_MIN: self.fHoverStep = self.HOVER_MIN + 1 QDial.enterEvent(self, event) def leaveEvent(self, event): self.fIsHovered = False if self.fHoverStep == self.HOVER_MAX: self.fHoverStep = self.HOVER_MAX - 1 QDial.leaveEvent(self, event) def mousePressEvent(self, event): if self.fDialMode == self.MODE_DEFAULT: return QDial.mousePressEvent(self, event) if event.button() == Qt.LeftButton: self.fIsPressed = True self.fLastDragPos = event.pos() self.fLastDragValue = self.fRealValue self.dragStateChanged.emit(True) def mouseMoveEvent(self, event): if self.fDialMode == self.MODE_DEFAULT: return QDial.mouseMoveEvent(self, event) if not self.fIsPressed: return range = (self.fMaximum - self.fMinimum) / 4.0 pos = event.pos() dx = range * float(pos.x() - self.fLastDragPos.x()) / self.width() dy = range * float(pos.y() - self.fLastDragPos.y()) / self.height() value = self.fLastDragValue + dx - dy if value < self.fMinimum: value = self.fMinimum elif value > self.fMaximum: value = self.fMaximum elif self.fIsInteger: value = float(round(value)) self.setValue(value, True) def mouseReleaseEvent(self, event): if self.fDialMode == self.MODE_DEFAULT: return QDial.mouseReleaseEvent(self, event) if self.fIsPressed: self.fIsPressed = False self.dragStateChanged.emit(False) def paintEvent(self, event): painter = QPainter(self) event.accept() painter.save() painter.setRenderHint(QPainter.Antialiasing, True) if self.fLabel: if self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_NULL: painter.setPen(self.fLabelGradientColor2) painter.setBrush(self.fLabelGradient) painter.drawRect(self.fLabelGradientRect) painter.setFont(self.fLabelFont) painter.setPen( self.fLabelGradientColorT[0 if self.isEnabled() else 1]) painter.drawText(self.fLabelPos, self.fLabel) if self.isEnabled(): normValue = float(self.fRealValue - self.fMinimum) / float(self.fMaximum - self.fMinimum) curLayer = int((self.fImageLayersCount - 1) * normValue) if self.fImageOrientation == self.HORIZONTAL: xpos = self.fImageBaseSize * curLayer ypos = 0.0 else: xpos = 0.0 ypos = self.fImageBaseSize * curLayer source = QRectF(xpos, ypos, self.fImageBaseSize, self.fImageBaseSize) if isinstance(self.fImage, QPixmap): target = QRectF(0.0, 0.0, self.fImageBaseSize, self.fImageBaseSize) painter.drawPixmap(target, self.fImage, source) else: self.fImage.renderer().render(painter, source) # Custom knobs (Dry/Wet and Volume) if self.fCustomPaintMode in (self.CUSTOM_PAINT_MODE_CARLA_WET, self.CUSTOM_PAINT_MODE_CARLA_VOL): # knob color colorGreen = QColor(0x5D, 0xE7, 0x3D).lighter(100 + self.fHoverStep * 6) colorBlue = QColor(0x3E, 0xB8, 0xBE).lighter(100 + self.fHoverStep * 6) # 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 * normValue) ballValue = tmpValue - floor(tmpValue) ballPoint = ballPath.pointAtPercent(ballValue) # draw arc startAngle = 218 * 16 spanAngle = -255 * 16 * normValue if self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_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.fCustomPaintMode in (self.CUSTOM_PAINT_MODE_CARLA_L, self.CUSTOM_PAINT_MODE_CARLA_R): # knob color color = QColor(0xAD, 0xD5, 0x48).lighter(100 + self.fHoverStep * 6) # 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 * normValue) 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.fCustomPaintMode == self.CUSTOM_PAINT_MODE_CARLA_L: startAngle = 218 * 16 spanAngle = -255 * 16 * normValue else: startAngle = 322.0 * 16 spanAngle = 255.0 * 16 * (1.0 - normValue) painter.setPen(QPen(color, 2.5)) painter.drawArc(3.5, 3.5, 22.0, 22.0, startAngle, spanAngle) # Custom knobs (Color) elif self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_COLOR: # knob color color = self.fCustomPaintColor.lighter(100 + self.fHoverStep * 6) # draw small circle ballRect = QRectF(8.0, 8.0, 15.0, 15.0) ballPath = QPainterPath() ballPath.addEllipse(ballRect) tmpValue = (0.375 + 0.75 * normValue) ballValue = tmpValue - floor(tmpValue) ballPoint = ballPath.pointAtPercent(ballValue) # draw arc startAngle = 218 * 16 spanAngle = -255 * 16 * normValue painter.setBrush(color) painter.setPen(QPen(color, 0)) painter.drawEllipse( QRectF(ballPoint.x(), ballPoint.y(), 2.2, 2.2)) painter.setBrush(color) painter.setPen(QPen(color, 3)) painter.drawArc(4.0, 4.8, 26.0, 26.0, startAngle, spanAngle) # Custom knobs (Zita) elif self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_ZITA: a = normValue * pi * 1.5 - 2.35 r = 10.0 x = 10.5 y = 10.5 x += r * sin(a) y -= r * cos(a) painter.setBrush(Qt.black) painter.setPen(QPen(Qt.black, 2)) painter.drawLine(QPointF(11.0, 11.0), QPointF(x, y)) # Custom knobs else: painter.restore() return if self.HOVER_MIN < self.fHoverStep < self.HOVER_MAX: self.fHoverStep += 1 if self.fIsHovered else -1 QTimer.singleShot(20, self.update) else: # isEnabled() target = QRectF(0.0, 0.0, self.fImageBaseSize, self.fImageBaseSize) if isinstance(self.fImage, QPixmap): painter.drawPixmap(target, self.fImage, target) else: self.fImage.renderer().render(painter, target) painter.restore() def resizeEvent(self, event): QDial.resizeEvent(self, event) self.updateSizes()
class DigitalPeakMeter(QWidget): # enum Color COLOR_GREEN = 1 COLOR_BLUE = 2 # enum Orientation HORIZONTAL = 1 VERTICAL = 2 # enum Style STYLE_DEFAULT = 1 STYLE_OPENAV = 2 STYLE_RNCBC = 3 STYLE_CALF = 4 # -------------------------------------------------------------------------------------------------------- def __init__(self, parent): QWidget.__init__(self, parent) self.setAttribute(Qt.WA_OpaquePaintEvent) # defaults are VERTICAL, COLOR_GREEN, STYLE_DEFAULT self.fChannelCount = 0 self.fChannelData = [] self.fLastChannelData = [] self.fMeterColor = self.COLOR_GREEN self.fMeterColorBase = QColor(93, 231, 61) self.fMeterColorBaseAlt = QColor(15, 110, 15, 100) self.fMeterLinesEnabled = True self.fMeterOrientation = self.VERTICAL self.fMeterStyle = self.STYLE_DEFAULT self.fMeterBackground = QColor("#070707") self.fMeterGradient = QLinearGradient(0, 0, 0, 0) self.fMeterPixmaps = () self.fSmoothMultiplier = 2 self.updateGrandient() # -------------------------------------------------------------------------------------------------------- def channelCount(self): return self.fChannelCount def setChannelCount(self, count): if self.fChannelCount == count: return if count < 0: return qCritical( "DigitalPeakMeter::setChannelCount(%i) - channel count must be a positive integer or zero" % count ) self.fChannelCount = count self.fChannelData = [] self.fLastChannelData = [] for x in range(count): self.fChannelData.append(0.0) self.fLastChannelData.append(0.0) if self.fMeterStyle == self.STYLE_CALF: if self.fChannelCount > 0: self.setFixedSize(100, 12 * self.fChannelCount) else: self.setMinimumSize(0, 0) self.setMaximumSize(9999, 9999) # -------------------------------------------------------------------------------------------------------- def meterColor(self): return self.fMeterColor def setMeterColor(self, color): if self.fMeterColor == color: return if color not in (self.COLOR_GREEN, self.COLOR_BLUE): return qCritical("DigitalPeakMeter::setMeterColor(%i) - invalid color" % color) if color == self.COLOR_GREEN: self.fMeterColorBase = QColor(93, 231, 61) self.fMeterColorBaseAlt = QColor(15, 110, 15, 100) elif color == self.COLOR_BLUE: self.fMeterColorBase = QColor(82, 238, 248) self.fMeterColorBaseAlt = QColor(15, 15, 110, 100) self.fMeterColor = color self.updateGrandient() # -------------------------------------------------------------------------------------------------------- def meterLinesEnabled(self): return self.fMeterLinesEnabled def setMeterLinesEnabled(self, yesNo): if self.fMeterLinesEnabled == yesNo: return self.fMeterLinesEnabled = yesNo # -------------------------------------------------------------------------------------------------------- def meterOrientation(self): return self.fMeterOrientation def setMeterOrientation(self, orientation): if self.fMeterOrientation == orientation: return if orientation not in (self.HORIZONTAL, self.VERTICAL): return qCritical("DigitalPeakMeter::setMeterOrientation(%i) - invalid orientation" % orientation) self.fMeterOrientation = orientation self.updateGrandient() # -------------------------------------------------------------------------------------------------------- def meterStyle(self): return self.fMeterStyle def setMeterStyle(self, style): if self.fMeterStyle == style: return if style not in (self.STYLE_DEFAULT, self.STYLE_OPENAV, self.STYLE_RNCBC, self.STYLE_CALF): return qCritical("DigitalPeakMeter::setMeterStyle(%i) - invalid style" % style) if style == self.STYLE_DEFAULT: self.fMeterBackground = QColor("#070707") elif style == self.STYLE_OPENAV: self.fMeterBackground = QColor("#1A1A1A") elif style == self.STYLE_RNCBC: self.fMeterBackground = QColor("#070707") elif style == self.STYLE_CALF: self.fMeterBackground = QColor("#000") if style == self.STYLE_CALF: self.fMeterPixmaps = (QPixmap(":/bitmaps/meter_calf_off.png"), QPixmap(":/bitmaps/meter_calf_on.png")) if self.fChannelCount > 0: self.setFixedSize(100, 12 * self.fChannelCount) else: self.fMeterPixmaps = () self.setMinimumSize(0, 0) self.setMaximumSize(9999, 9999) self.fMeterStyle = style self.updateGrandient() # -------------------------------------------------------------------------------------------------------- def smoothMultiplier(self): return self.fSmoothMultiplier def setSmoothMultiplier(self, value): if self.fSmoothMultiplier == value: return if not isinstance(value, int): return qCritical("DigitalPeakMeter::setSmoothMultiplier() - value must be an integer") if value < 0: return qCritical("DigitalPeakMeter::setSmoothMultiplier(%i) - value must be >= 0" % value) if value > 5: return qCritical("DigitalPeakMeter::setSmoothMultiplier(%i) - value must be < 5" % value) self.fSmoothMultiplier = value # -------------------------------------------------------------------------------------------------------- def displayMeter(self, meter, level, forced=False): if not isinstance(meter, int): return qCritical("DigitalPeakMeter::displayMeter(,) - meter value must be an integer") if not isinstance(level, float): return qCritical("DigitalPeakMeter::displayMeter(%i,) - level value must be a float" % (meter,)) if meter <= 0 or meter > self.fChannelCount: return qCritical("DigitalPeakMeter::displayMeter(%i, %f) - invalid meter number" % (meter, level)) i = meter - 1 if self.fSmoothMultiplier > 0 and not forced: level = (self.fLastChannelData[i] * float(self.fSmoothMultiplier) + level) / float( self.fSmoothMultiplier + 1 ) if level < 0.001: level = 0.0 elif level > 0.999: level = 1.0 if self.fChannelData[i] != level: self.fChannelData[i] = level self.update() self.fLastChannelData[i] = level # -------------------------------------------------------------------------------------------------------- def updateGrandient(self): self.fMeterGradient = QLinearGradient(0, 0, 1, 1) if self.fMeterStyle == self.STYLE_DEFAULT: if self.fMeterOrientation == self.HORIZONTAL: self.fMeterGradient.setColorAt(0.0, self.fMeterColorBase) self.fMeterGradient.setColorAt(0.2, self.fMeterColorBase) self.fMeterGradient.setColorAt(0.4, self.fMeterColorBase) self.fMeterGradient.setColorAt(0.6, self.fMeterColorBase) self.fMeterGradient.setColorAt(0.8, Qt.yellow) self.fMeterGradient.setColorAt(1.0, Qt.red) elif self.fMeterOrientation == self.VERTICAL: self.fMeterGradient.setColorAt(0.0, Qt.red) self.fMeterGradient.setColorAt(0.2, Qt.yellow) self.fMeterGradient.setColorAt(0.4, self.fMeterColorBase) self.fMeterGradient.setColorAt(0.6, self.fMeterColorBase) self.fMeterGradient.setColorAt(0.8, self.fMeterColorBase) self.fMeterGradient.setColorAt(1.0, self.fMeterColorBase) elif self.fMeterStyle == self.STYLE_RNCBC: if self.fMeterColor == self.COLOR_BLUE: c1 = QColor(40, 160, 160) c2 = QColor(60, 220, 160) elif self.fMeterColor == self.COLOR_GREEN: c1 = QColor(40, 160, 40) c2 = QColor(160, 220, 20) if self.fMeterOrientation == self.HORIZONTAL: self.fMeterGradient.setColorAt(0.0, c1) self.fMeterGradient.setColorAt(0.2, c1) self.fMeterGradient.setColorAt(0.6, c2) self.fMeterGradient.setColorAt(0.7, QColor(220, 220, 20)) self.fMeterGradient.setColorAt(0.8, QColor(240, 160, 20)) self.fMeterGradient.setColorAt(0.9, QColor(240, 0, 20)) self.fMeterGradient.setColorAt(1.0, QColor(240, 0, 20)) elif self.fMeterOrientation == self.VERTICAL: self.fMeterGradient.setColorAt(0.0, QColor(240, 0, 20)) self.fMeterGradient.setColorAt(0.1, QColor(240, 0, 20)) self.fMeterGradient.setColorAt(0.2, QColor(240, 160, 20)) self.fMeterGradient.setColorAt(0.3, QColor(220, 220, 20)) self.fMeterGradient.setColorAt(0.4, c2) self.fMeterGradient.setColorAt(0.8, c1) self.fMeterGradient.setColorAt(1.0, c1) elif self.fMeterStyle in (self.STYLE_OPENAV, self.STYLE_CALF): self.fMeterGradient.setColorAt(0.0, self.fMeterColorBase) self.fMeterGradient.setColorAt(1.0, self.fMeterColorBase) self.updateGrandientFinalStop() def updateGrandientFinalStop(self): if self.fMeterOrientation == self.HORIZONTAL: self.fMeterGradient.setFinalStop(self.width(), 0) elif self.fMeterOrientation == self.VERTICAL: self.fMeterGradient.setFinalStop(0, self.height()) # -------------------------------------------------------------------------------------------------------- def minimumSizeHint(self): return QSize(10, 10) def sizeHint(self): return QSize(self.width(), self.height()) # -------------------------------------------------------------------------------------------------------- def drawCalf(self, event): painter = QPainter(self) event.accept() # no channels, draw black if self.fChannelCount == 0: painter.setPen(QPen(Qt.black, 2)) painter.setBrush(Qt.black) painter.drawRect(0, 0, self.width(), self.height()) return for i in range(self.fChannelCount): painter.drawPixmap(0, 12 * i, self.fMeterPixmaps[0]) meterPos = 4 meterSize = 12 # draw levels for level in self.fChannelData: if level != 0.0: blevel = int(sqrt(level) * 26.0) * 3 painter.drawPixmap(5, meterPos, blevel, 4, self.fMeterPixmaps[1], 0, 0, blevel, 4) meterPos += meterSize def paintEvent(self, event): if self.fMeterStyle == self.STYLE_CALF: return self.drawCalf(event) painter = QPainter(self) event.accept() width = self.width() height = self.height() # draw background painter.setPen(QPen(self.fMeterBackground, 2)) painter.setBrush(self.fMeterBackground) painter.drawRect(0, 0, width, height) if self.fChannelCount == 0: return meterPad = 0 meterPos = 0 meterSize = (height if self.fMeterOrientation == self.HORIZONTAL else width) / self.fChannelCount # set pen/brush for levels if self.fMeterStyle == self.STYLE_OPENAV: colorTrans = QColor(self.fMeterColorBase) colorTrans.setAlphaF(0.5) painter.setBrush(colorTrans) painter.setPen(QPen(self.fMeterColorBase, 1)) del colorTrans meterPad += 2 meterSize -= 2 else: painter.setPen(QPen(self.fMeterBackground, 0)) painter.setBrush(self.fMeterGradient) # draw levels for level in self.fChannelData: if level == 0.0: pass elif self.fMeterOrientation == self.HORIZONTAL: painter.drawRect(0, meterPos, int(sqrt(level) * float(width)), meterSize) elif self.fMeterOrientation == self.VERTICAL: painter.drawRect(meterPos, height - int(sqrt(level) * float(height)), meterSize, height) meterPos += meterSize + meterPad if not self.fMeterLinesEnabled: return # draw lines if self.fMeterOrientation == self.HORIZONTAL: # Variables lsmall = float(width) lfull = float(height - 1) if self.fMeterStyle == self.STYLE_OPENAV: painter.setPen(QColor(37, 37, 37, 100)) painter.drawLine(lsmall * 0.25, 2, lsmall * 0.25, lfull - 2.0) painter.drawLine(lsmall * 0.50, 2, lsmall * 0.50, lfull - 2.0) painter.drawLine(lsmall * 0.75, 2, lsmall * 0.75, lfull - 2.0) if self.fChannelCount > 1: painter.drawLine(1, lfull / 2 - 1, lsmall - 1, lfull / 2 - 1) else: # Base painter.setBrush(Qt.black) painter.setPen(QPen(self.fMeterColorBaseAlt, 1)) painter.drawLine(lsmall * 0.25, 2, lsmall * 0.25, lfull - 2.0) painter.drawLine(lsmall * 0.50, 2, lsmall * 0.50, lfull - 2.0) # Yellow painter.setPen(QColor(110, 110, 15, 100)) painter.drawLine(lsmall * 0.70, 2, lsmall * 0.70, lfull - 2.0) painter.drawLine(lsmall * 0.83, 2, lsmall * 0.83, lfull - 2.0) # Orange painter.setPen(QColor(180, 110, 15, 100)) painter.drawLine(lsmall * 0.90, 2, lsmall * 0.90, lfull - 2.0) # Red painter.setPen(QColor(110, 15, 15, 100)) painter.drawLine(lsmall * 0.96, 2, lsmall * 0.96, lfull - 2.0) elif self.fMeterOrientation == self.VERTICAL: # Variables lsmall = float(height) lfull = float(width - 1) if self.fMeterStyle == self.STYLE_OPENAV: painter.setPen(QColor(37, 37, 37, 100)) painter.drawLine(2, lsmall - (lsmall * 0.25), lfull - 2.0, lsmall - (lsmall * 0.25)) painter.drawLine(2, lsmall - (lsmall * 0.50), lfull - 2.0, lsmall - (lsmall * 0.50)) painter.drawLine(2, lsmall - (lsmall * 0.75), lfull - 2.0, lsmall - (lsmall * 0.75)) if self.fChannelCount > 1: painter.drawLine(lfull / 2 - 1, 1, lfull / 2 - 1, lsmall - 1) else: # Base painter.setBrush(Qt.black) painter.setPen(QPen(self.fMeterColorBaseAlt, 1)) painter.drawLine(2, lsmall - (lsmall * 0.25), lfull - 2.0, lsmall - (lsmall * 0.25)) painter.drawLine(2, lsmall - (lsmall * 0.50), lfull - 2.0, lsmall - (lsmall * 0.50)) # Yellow painter.setPen(QColor(110, 110, 15, 100)) painter.drawLine(2, lsmall - (lsmall * 0.70), lfull - 2.0, lsmall - (lsmall * 0.70)) painter.drawLine(2, lsmall - (lsmall * 0.82), lfull - 2.0, lsmall - (lsmall * 0.82)) # Orange painter.setPen(QColor(180, 110, 15, 100)) painter.drawLine(2, lsmall - (lsmall * 0.90), lfull - 2.0, lsmall - (lsmall * 0.90)) # Red painter.setPen(QColor(110, 15, 15, 100)) painter.drawLine(2, lsmall - (lsmall * 0.96), lfull - 2.0, lsmall - (lsmall * 0.96)) # -------------------------------------------------------------------------------------------------------- def resizeEvent(self, event): QWidget.resizeEvent(self, event) self.updateGrandientFinalStop()
class ColorSlider(QWidget): Orientation = utils.enum('HORIZONTAL', 'VERTICAL') valueChanged = pyqtSignal(int) pickerPoly = QPolygon([ QPoint(0, 13), QPoint(16, 13), QPoint(8, 0) ]) def __init__(self, min_value, max_value, alpha=None): super(ColorSlider, self).__init__() self._value = min_value self._minValue = min_value self._maxValue = max_value self._pickerWidth = 8 self._sliding = False self._pickRect = QRect() self._slideStep = 10 self._orientation = self.Orientation.HORIZONTAL self._label = "" self._gradient = None self._pickerPixmap = None self._background = None self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self._update_gradient() self._update_picker_position() self._generate_picker() if alpha is not None: self._background = utils.generate_checkerboard_tile(8, QColor(150, 150, 150), QColor(175, 175, 175)) @property def label(self): return self._label @label.setter def label(self, value): self._label = value @property def value(self): return self._value @value.setter def value(self, value): value = max(self._minValue, min(value, self._maxValue)) if value != self._value: self._value = int(round(value)) self._update_picker_position() self.update() @property def max_value(self): return self._maxValue @max_value.setter def max_value(self, value): if value < self._minValue: value = self._minValue self._maxValue = value @property def step(self): return self._slideStep @step.setter def step(self, value): self._slideStep = value @property def start_color(self): return self._gradient.getColorAt(0.0) @start_color.setter def start_color(self, value): self._gradient.setColorAt(0.0, value) @property def end_color(self): return self._gradient.getColorAt(1.0) @end_color.setter def end_color(self, value): self._gradient.setColorAt(1.0, value) def _update_gradient(self): if self._gradient is None: self._gradient = QLinearGradient() self._gradient.setStart(0, 0) if self._orientation == self.Orientation.HORIZONTAL: self._gradient.setFinalStop(self.width(), 0) else: self._gradient.setFinalStop(0, self.height()) def set_color_at(self, pos, color): pos = max(0, min(pos, 1)) self._gradient.setColorAt(pos, color) def _position_to_value(self, pos): pos -= self._pickerWidth / 2.0 size = float(self.width()) - self._pickerWidth if \ self._orientation == self.Orientation.HORIZONTAL else \ float(self.height()) - self._pickerWidth if self._orientation == self.Orientation.VERTICAL: pos = round(size - pos) if pos > size: return self._maxValue if pos < 0: return self._minValue percent = float(pos) / float(size) return round((self._maxValue - self._minValue) * percent) def _update_picker_position(self): size = float(self.width()) - self._pickerWidth \ if self._orientation == self.Orientation.HORIZONTAL \ else float(self.height()) - self._pickerWidth pos = round(max(0, min(size * (float(self._value - self._minValue) / float(self._maxValue - self._minValue)), size))) if self._orientation == self.Orientation.VERTICAL: pos = round(size - pos) if self._orientation == self.Orientation.HORIZONTAL: self._pickRect = QRect(pos, 13, self._pickerWidth, 18) else: self._pickRect = QRect(13, pos, self._pickerWidth, 18) def _generate_picker(self): image = QImage(8, 18, QImage.Format_ARGB32_Premultiplied) image.fill(Qt.transparent) p = QPainter() p.begin(image) pen = QPen(Qt.black) pen.setWidth(2) p.setPen(pen) p.setBrush(Qt.white) rect = QRect(0, 0, 8, 18) p.drawRect(rect) p.end() self._pickerPixmap = QPixmap.fromImage(image) def sizeHint(self): return QSize(223, 30) def mousePressEvent(self, e): self._sliding = True mouse_pos = e.pos().x() if self._orientation == self.Orientation.HORIZONTAL else \ e.pos().y() self.value = self._position_to_value(mouse_pos) self.valueChanged.emit(self._value) def mouseReleaseEvent(self, e): if self._sliding: self._sliding = False self.update() def mouseMoveEvent(self, e): if not self._sliding: return self.value = self._position_to_value(e.pos().x()) self.valueChanged.emit(self._value) def wheelEvent(self, e): self.value = self._value + utils.sign(e.angleDelta().y()) * self._slideStep self.valueChanged.emit(self._value) def resizeEvent(self, e): self._update_picker_position() self._update_gradient() def paintEvent(self, e): p = QPainter(self) # Paint border bar_rect = self.rect().adjusted(0, 15, 0, -1) if self._background is not None: p.drawTiledPixmap(bar_rect, self._background) pen = QPen() pen.setColor(Qt.black) pen.setWidth(1) p.setPen(pen) bar_rect.adjust(0, 0, -1, 0) p.drawRect(bar_rect) p.setPen(Qt.white) # Paint Spectrum bar_rect.adjust(1, 1, 0, 0) p.fillRect(bar_rect, QBrush(self._gradient)) # Paint Picker p.drawPixmap(self._pickRect, self._pickerPixmap) # Draw Label label_rect = QRect(200, 1, 20, 15) p.drawText(label_rect, Qt.AlignRight, str(self._value)) if len(self._label) > 0: label_rect.adjust(-200, 0, 0, 0) p.drawText(label_rect, Qt.AlignLeft, self._label)
class DQuickWidget(FMoveableWidget): def __init__(self): super(DQuickWidget, self).__init__() self.resize(1000, 100) self.setMinimumSize(100, 80) self.linear_gradient = QLinearGradient() self.linear_gradient.setStart(0, 10) self.linear_gradient.setFinalStop(0, 40) self.linear_gradient.setColorAt(0.1, QColor(14, 179, 255)) self.linear_gradient.setColorAt(0.5, QColor(114, 232, 255)) self.linear_gradient.setColorAt(0.9, QColor(14, 179, 255)) self.mask_linear_gradient = QLinearGradient() self.mask_linear_gradient.setStart(0, 10) self.mask_linear_gradient.setFinalStop(0, 40) self.mask_linear_gradient.setColorAt(0.1, QColor(222, 54, 4)) self.mask_linear_gradient.setColorAt(0.5, QColor(255, 72, 16)) self.mask_linear_gradient.setColorAt(0.9, QColor(222, 54, 4)) self.text = "PyQt 5.2版本最新发布了,Qt 库的Python绑定" self.font = QFont() self.font.setFamily("Times New Roman") self.font.setBold(True) self.font.setPixelSize(30) self.setFont(self.font) self.timer = QTimer(self) self.timer.setInterval(100) self.timer.timeout.connect(self.update) self.timer.start() self.textWidth = self.fontMetrics().width(self.text) self.textHeight = self.fontMetrics().height() self.p = 0.1 self.button = QPushButton('1111', self) self.button.move(100, 0) self.button.resize(40, 40) self.toolBarHeight = 50 def paintEvent(self, event): self.startX = (self.width() - self.textWidth) / 2 self.startY = self.toolBarHeight + ( self.height() - self.toolBarHeight - self.textHeight) / 2 painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) # pixelSize = self.font.pixelSize() # pixelSize += 1 # self.font.setPixelSize(pixelSize) # self.setFont(self.font) # self.textHeight = self.fontMetrics().height() # spacing = (self.height() - self.toolBarHeight - self.textHeight) / 2 # # if spacing > 0: painter.setFont(self.font) if self.boderFlag: color = QColor('lightgray') color.setAlpha(30) painter.fillRect(0, self.toolBarHeight, self.width(), self.height() - self.toolBarHeight, color) painter.setPen(QColor(0, 0, 0, 200)) painter.drawText(self.startX + 1, self.startY + 1, self.textWidth, self.textHeight, Qt.AlignLeft, self.text) painter.setPen(QPen(self.linear_gradient, 0)) painter.drawText(self.startX, self.startY, self.textWidth, self.textHeight, Qt.AlignLeft, self.text) painter.setPen(QPen(self.mask_linear_gradient, 0)) painter.drawText(self.startX, self.startY, self.textWidth * self.p, self.textHeight, Qt.AlignLeft, self.text) self.p += 0.01 if self.p >= 1: self.p = 0 self.font.setPixelSize(30)