• PyQt5自定义组件之飞机水平仪


    PyQt5自定义组件之飞机水平仪

    效果如下图:

    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    from PyQt5.QtWidgets import *
    
    
    class GaugePlane(QWidget):
        def __init__(self, parent=None):
            super(GaugePlane, self).__init__(parent)
            self.initUI()
    
        def initUI(self):
            self.borderOutColorStart = Qt.black
            self.borderOutColorEnd = QColor(23, 149, 166)
    
            self.borderInColorStart = QColor(50, 50, 50)
            self.borderInColorEnd = QColor(220, 220, 220)
    
    
            self.bgColor = QColor(41, 127, 184)
            self.planeColor = QColor("#d68070")
            self.glassColor = QColor(250, 250, 250)
            self.scaleColor = QColor(255, 255, 255)
            self.lineColor = QColor(255, 255, 255)
            self.textColor = QColor(255, 255, 255)
            self.pointerColor = QColor(255, 107, 107)
            self.handleColor = QColor("grey")
    
            self.degValue = 0  # 倾斜角
            self.rollValue = 0  # 俯仰角
    
            self.resize(400, 400)
    
            self.time = QTimer()
            self.time.start(1000)
            self.time.timeout.connect(self.tsetDegValue)
    
        def paintEvent(self, QPaintEvent):
            width = self.width()
            height = self.height()
            side = min(width, height)
    
            # 绘制准备工作, 启用反锯齿, 平移坐标轴中心, 等比例缩放
            painter = QPainter(self)
            painter.setRenderHints(QPainter.Antialiasing | QPainter.TextAntialiasing)
            painter.translate(width / 2, height / 2)
            painter.scale(side / 200.0, side / 200.0)
    
            # 绘制外边框
            self.drawBorderOut(painter)
            # 绘制内边框
            self.drawBorderIn(painter)
            # 绘制背景
            self.drawBg(painter)
            # 绘制姿势仪背景
            self.drawPlane(painter)
            # 绘制玻璃遮罩层
            self.drawGlass(painter)
            # 绘制刻度尺
            self.drawScale(painter)
            # 绘制线条
            self.drawLine(painter)
            # 绘制指针
            self.drawPointer(painter)
            # 绘制手柄
            self.drawHandle(painter)
    
        def tsetDegValue(self):
            import random
            dev = random.randint(-30, 30)
            roll = random.randint(-30, 30)
            self.setRollValue(roll)
            self.setDegValue(dev)
    
        def drawBorderOut(self, painter):
            radius = 99
            painter.save()
            painter.setPen(Qt.NoPen)
    
            borderGradient = QLinearGradient(0, -radius, 0, radius)
            borderGradient.setColorAt(0, self.borderOutColorStart)
            borderGradient.setColorAt(1, self.borderOutColorEnd)
            painter.setBrush(borderGradient)
            painter.drawEllipse(-radius, -radius, radius * 2, radius * 2)
            painter.restore()
    
        def drawBorderIn(self, painter):
            radius = 93
            painter.save()
            painter.setPen(Qt.NoPen)
            borderGradient = QLinearGradient(0, -radius, 0, radius)
            borderGradient.setColorAt(0, self.borderInColorStart)
            borderGradient.setColorAt(1, self.borderInColorEnd)
            painter.setBrush(borderGradient)
            painter.drawEllipse(-radius, -radius, radius * 2, radius * 2)
            painter.restore()
    
        def drawBg(self, painter):
            radius = 90
            painter.save()
            painter.setPen(Qt.NoPen)
    
            borderGradient = QLinearGradient(0, -radius, 0, radius)
            self.bgColor.setAlpha(255)
            borderGradient.setColorAt(0, self.bgColor)
            self.bgColor.setAlpha(150)
            borderGradient.setColorAt(1, self.bgColor)
            painter.setBrush(borderGradient)
            painter.drawEllipse(-radius, -radius, radius * 2, radius * 2)
            painter.restore()
    
        def drawPlane(self, painter):
            radius = 90
            painter.save()
            painter.rotate(self.degValue)
            painter.setPen(Qt.NoPen)
            painter.setBrush(self.planeColor)
            rect = QRect(-radius, -radius, radius * 2, radius * 2)
    
            if not painter:
                painter.drawPie(rect, 0, -16 * 180)
            else:
                offset = -(self.rollValue * radius / 60)
                startAngle = 180 + offset
                endAngle = offset
                span = endAngle + startAngle
                painter.drawChord(rect, -16 * startAngle, 16 * span)
            painter.restore()
    
        def drawGlass(self, painter):
            radius = 80
            painter.save()
            painter.setPen(Qt.NoPen)
            # 饼圆1为整个圆形区域
            pieRect1 = QRect(-radius, -radius, radius * 2, radius * 2)
            # 饼圆2位饼圆1区域的中间部分的四分之一
            pieRect2 = QRect(-radius, -radius / 4, radius * 2, radius / 4 * 2)
            # 颜色线性渐变, 颜色透明度产生立体感
            linearGradient = QLinearGradient(pieRect1.topLeft(), pieRect1.bottomRight())
            self.glassColor.setAlpha(30)
            linearGradient.setColorAt(0.1, self.glassColor)
            self.glassColor.setAlpha(100)
            linearGradient.setColorAt(0.5, self.glassColor)
            # 绘制两个饼圆
            painter.setBrush(linearGradient)
            painter.drawPie(pieRect1, 0, 16 * 180)
            painter.drawPie(pieRect2, 0, -16 * 180)
            painter.restore()
    
        def drawScale(self, painter):
            radius = 88
            painter.save()
            # 设置画笔颜色
            pen = QPen()
            pen.setColor(self.scaleColor)
            pen.setWidthF(4)
            pen.setCapStyle(Qt.RoundCap)
            painter.setPen(pen)
            # 线条长度
            len = 8
            # 左侧平行线
            painter.rotate(90)
            painter.drawLine(0, radius - len, 0, radius)
            # 逐个绘制大刻度
            for i in range(6):
                painter.rotate(30)
                painter.drawLine(0, radius - len, 0, radius)
    
            # 回到小刻度,重新设置画笔宽度
            pen.setWidthF(2)
            painter.setPen(pen)
            painter.rotate(-120)
            # 逐个绘制小刻度
            for i in range(5):
                painter.rotate(10)
                painter.drawLine(0, radius - len, 0, radius)
            painter.restore()
    
        def drawLine(self, painter):
            radius = 95
            painter.save()
            width = self.width()
            height = self.height()
            side = min(width, height)
    
            # 重置坐标系
            painter.resetTransform()
            painter.translate(width / 2, height / 2 + self.rollValue)
            painter.scale(side / 200.0, side / 200.0)
    
            painter.rotate(self.degValue)
    
            # 设置画笔颜色
            pen = QPen()
            pen.setColor(self.lineColor)
            pen.setWidthF(2)
            pen.setCapStyle(Qt.RoundCap)
            painter.setPen(pen)
    
            # 设置画笔字体
            font = QFont()
            font.setPixelSize(10)
            font.setBold(True)
            painter.setFont(font)
    
            # 依次绘制水平距离线条及值
    
            i = -30
            while i <= 30:
                if i == 0:
                    # 中心点不用绘制
                    i += 10
                    continue
                value = qAbs(i)
    
                # 绘制横向水平线条
    
                pt1 = QPointF(-radius * value / 100, radius / 70 * i)
    
                pt2 = QPointF(-pt1.x(), pt1.y())
                painter.drawLine(pt1, pt2)
    
                # 根据字体大小计算绘制文字的区域
                # strValue = QString.number(value)
                strValue = str(value).replace(".0", "")
                fm = painter.fontMetrics()
                textRect = QRectF(QPointF(QPoint(0, 0)), QSizeF(fm.size(Qt.AlignCenter, strValue)))
                textRect.moveCenter(pt1 - QPointF(radius / 10, 0))
                painter.drawText(textRect, Qt.AlignCenter, strValue)
    
                textRect.moveCenter(pt2 + QPointF(radius / 10, 0))
                painter.drawText(textRect, Qt.AlignCenter, strValue)
                i += 10
            painter.restore()
    
        def drawPointer(self, painter):
            radius = 70
            painter.save()
            painter.rotate(self.degValue + 90)
            painter.setPen(Qt.NoPen)
            # 指针长度
            len = 10
            # 三角形坐标
            pts = QPolygon()
            pts.setPoints(-radius, 0, -radius + len, -len / 2, -radius + len, len / 2)
            painter.setBrush(self.pointerColor)
            painter.drawConvexPolygon(pts)
            painter.restore()
    
        def drawHandle(self, painter):
            painter.save()
            pen = QPen()
            pen.setColor(self.handleColor)
            pen.setWidthF(4)
            pen.setCapStyle(Qt.RoundCap)
            pen.setJoinStyle(Qt.MiterJoin)
            painter.setPen(pen)
            painter.setBrush(self.handleColor)
            # 绘制弧形
            arcRadius = 15
            rect = QRect(-arcRadius, -arcRadius, arcRadius * 2, arcRadius * 2)
            painter.drawArc(rect, 0, -16 * 180)
            # 绘制中心圆
            centerRadius = 2
            rect = QRect(-centerRadius, -centerRadius, centerRadius * 2, centerRadius * 2)
            painter.drawEllipse(rect)
    
            # 绘制左侧右侧横向水平线条
            len = 30
            pt1 = QPoint(-len, 0)
            pt2 = QPoint(-arcRadius, 0)
            painter.drawLine(pt1, pt2)
    
            pt1 = QPoint(len, 0)
            pt2 = QPoint(arcRadius, 0)
            painter.drawLine(pt1, pt2)
    
            # 绘制纵向垂直线条
            pt1 = QPoint(0, len / 2)
            pt2 = QPoint(0, 80)
            painter.drawLine(pt1, pt2)
    
            # 绘制底部梯形
            p1 = QPoint(-30, 82)
            p2 = QPoint(-20, 60)
            p3 = QPoint(20, 60)
            p4 = QPoint(30, 82)
            pts = QPolygon([p1, p2, p3, p4])
    
            # pts << p1 << p2 << p3 << p4
            # pts.setPoints()
            painter.drawConvexPolygon(pts)
            # 绘制底部填充圆弧
            radius = 32
            rect = QRect(-radius, 77, radius * 2, 13)
            painter.setPen(Qt.NoPen)
            painter.drawPie(rect, 0, -16 * 180)
            painter.restore()
    
        def getBorderOutColorStart(self):
            return self.borderOutColorStart
    
        def getBorderOutColorEnd(self):
            return self.borderOutColorEnd
    
        def getBorderInColorStart(self):
            return self.borderInColorStart
    
        def getBorderInColorEnd(self):
            return self.borderInColorEnd
    
        def getBgColor(self):
            return self.bgColor
    
        def getPlaneColor(self):
            return self.planeColor
    
        def getGlassColor(self):
            return self.glassColor
    
        def getScaleColor(self):
            return self.scaleColor
    
        def getLineColor(self):
            return self.lineColor
    
        def getTextColor(self):
            return self.textColor
    
        def getPointerColor(self):
            return self.pointerColor
    
        def getHandleColor(self):
            return self.handleColor
    
        def getDegValue(self):
            return self.degValue
    
        def getRollValue(self):
            return self.rollValue
    
        def sizeHint(self):
            return QSize(200, 200)
    
        def minimumSizeHint(self):
            return QSize(50, 50)
    
        def setBorderOutColorStart(self, borderOutColorStart):
            if (self.borderOutColorStart != borderOutColorStart):
                self.borderOutColorStart = borderOutColorStart
                self.update()
    
        def setBorderOutColorEnd(self, borderOutColorEnd):
            if (self.borderOutColorEnd != borderOutColorEnd):
                self.borderOutColorEnd = borderOutColorEnd
                self.update()
    
        def setBorderInColorStart(self, borderInColorStart):
            if (self.borderInColorStart != borderInColorStart):
                self.borderInColorStart = borderInColorStart
                self.update()
    
        def setBorderInColorEnd(self, borderInColorEnd):
            if (self.borderInColorEnd != borderInColorEnd):
                self.borderInColorEnd = borderInColorEnd
                self.update()
    
        def setBgColor(self, bgColor):
            if (self.bgColor != bgColor):
                self.bgColor = bgColor
                self.update()
    
        def setPlaneColor(self, planeColor):
            if (self.planeColor != planeColor):
                self.planeColor = planeColor
                self.update()
    
        def setGlassColor(self, glassColor):
            if (self.glassColor != glassColor):
                self.glassColor = glassColor
                self.update()
    
        def setScaleColor(self, scaleColor):
            if (self.scaleColor != scaleColor):
                self.scaleColor = scaleColor
                self.update()
    
        def setLineColor(self, lineColor):
            if (self.lineColor != lineColor):
                self.lineColor = lineColor
                self.update()
    
        def setTextColor(self, textColor):
            if (self.textColor != textColor):
                self.textColor = textColor
                self.update()
    
        def setPointerColor(self, pointerColor):
            if (self.pointerColor != pointerColor):
                self.pointerColor = pointerColor
                self.update()
    
        def setHandleColor(self, handleColor):
            if (self.handleColor != handleColor):
                self.handleColor = handleColor
                self.update()
    
        def setDegValue(self, degValue):
            if (self.degValue != degValue and degValue >= -180 and degValue <= 180):
                self.degValue = degValue
                self.update()
    
        def setRollValue(self, rollValue):
            if (self.rollValue != rollValue and rollValue >= -100 and rollValue <= 100):
                self.rollValue = rollValue
                self.update()
    
    
    import sys
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        mainWindow = GaugePlane()
        mainWindow.show()
        sys.exit(app.exec_())
    
  • 相关阅读:
    C语言数据类型大学霸IT达人
    无线攻击工具MDK3常用命令大学霸IT达人
    WPS漏洞利用工具Bully常见命令集合
    无线密码离线破解工具Pyrit常用命令集合大学霸IT达人
    Wifite工具常用命令集合大学霸IT达人
    Linux防火墙命令大全
    详解nginx的rewrite应用,Nginx高级之Rewrite规则
    Nginx常用屏蔽规则,让你的网站更安全
    Nginx与安全有关的几个配置
    systemd 和 systemctl 使用深入理解
  • 原文地址:https://www.cnblogs.com/zyyhxbs/p/12667271.html
Copyright © 2020-2023  润新知