【Python】PyQt5 指示灯控件的制作,以及窗口动态添加、删除指示灯控件

一、效果图

1.1 指示灯效果图

【Python】PyQt5 指示灯控件的制作,以及窗口动态添加、删除指示灯控件_第1张图片

1.2 指示灯组效果图

【Python】PyQt5 指示灯控件的制作,以及窗口动态添加、删除指示灯控件_第2张图片

二、自定义指示灯控件

2.1 导入需要的包

import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

2.2 配置指示灯颜色

分别为:‘灯亮圆心颜色’, ‘灯亮边缘颜色’, ‘灯灭圆心颜色’,‘灯灭边缘颜色’,‘边框内测颜色’,‘边框外侧颜色’。

allAttributes = ['colorOnBegin', 'colorOnEnd', 'colorOffBegin', 'colorOffEnd', 'colorBorderIn', 'colorBorderOut']
allDefaultVal = [QColor(0, 180, 0), QColor(0, 150, 0), QColor(220, 0, 0), QColor(180, 0, 0), QColor(140, 140, 140),
                 QColor(100, 100, 100)]

2.3 创建自定义类并初始化

class MyLed(QAbstractButton):
    def __init__(self, parent=None):
        super(MyLed, self).__init__(parent)
        self.initUI()

    def initUI(self):
        self.setMinimumSize(24, 24)
        self.setCheckable(True)
        self.scaledSize = 1000.0  # 为方便计算,将窗口短边值映射为1000
        self.setLedDefaultOption()
        self.radiusBorderOut = 500  # 边框外侧半径
        self.radiusBorderIn = 450   # 边框内侧半径
        self.radiusCircle = 400     # 中间圆灯半径
        
	# 将配置的颜色和属性对应
    def setLedDefaultOption(self):
        for attr, val in zip(allAttributes, allDefaultVal):
            setattr(self, attr, val)
        self.update()
        
    def resizeEvent(self, evt):
        self.update()

2.4 重写paintEvent函数,绘制led

   def paintEvent(self, evt):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing, True)
        painter.setPen(QPen(Qt.black, 1))

        realSize = min(self.width(), self.height())  # 窗口的短边
        painter.translate(self.width() / 2.0, self.height() / 2.0)  # 原点平移到窗口中心
        painter.scale(realSize / self.scaledSize, realSize / self.scaledSize)  # 缩放,窗口的短边值映射为self.scaledSize
        gradient = QRadialGradient(QPointF(0, 0), self.scaledSize / 2.0, QPointF(0, 0))  # 辐射渐变

        # 画边框外圈和内圈
        for color, radius in [(self.colorBorderOut, self.radiusBorderOut),  # 边框外圈
                              (self.colorBorderIn, self.radiusBorderIn)]:   # 边框内圈
            gradient.setColorAt(1, color)
            painter.setBrush(QBrush(gradient))
            painter.drawEllipse(QPointF(0, 0), radius, radius)

        # 画内圆
        gradient.setColorAt(0, self.colorOnBegin if self.isChecked() else self.colorOffBegin)
        gradient.setColorAt(1, self.colorOnEnd if self.isChecked() else self.colorOffEnd)
        painter.setBrush(QBrush(gradient))
        painter.drawEllipse(QPointF(0, 0), self.radiusCircle, self.radiusCircle)

三、在窗口中动态添加、删除指示灯控件

3.1 将控件导入主窗口

from myLed import MyLed

3.2 动态添加指示灯

self.ledGroup = []
for r in range(self.row):  # 行
	# 添加垂直控件
    exec('self.boxLayout_{} = QtWidgets.QHBoxLayout()'.format(r))
    exec('self.boxLayout_{}.setObjectName("boxLayout_{}")'.format(r, r))
    for c in range(self.col):  # 列
        led = MyLed()
        led.setEnabled(False)  # 设置为不使能状态,如果需要切换可以设置为True。则可以实现点击切换指示灯颜色的效果
        led.setChecked(True)  # 设置为选中状态
        led.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.ledGroup.append(led)
        exec('self.boxLayout_{}.addWidget(led)'.format(r))
    # 添加到水平控件中
    exec('self.verticalLayout_3.addLayout(self.boxLayout_{})'.format(r))

3.3 动态删除指示灯

使用deleteLater()从窗口中移除控件,但是在ledGroup中并未完全删除控件,所以需要在pop()一下,才能完全从ledGroup中删除控件

for i in range(len(self.ledGroup)):
    self.ledGroup[0].deleteLater()
    self.ledGroup.pop(0)

3.4 部分代码

在添加之前先把之前的控件删除

def addLabel(self):
    for i in range(len(self.ledGroup)):
        self.ledGroup[0].deleteLater()
        self.ledGroup.pop(0)
    print(len(self.ledGroup))
    for r in range(self.ChildConfigure.motorNum):
        exec('self.boxLayout_{} = QtWidgets.QHBoxLayout()'.format(r))
        exec('self.boxLayout_{}.setObjectName("boxLayout_{}")'.format(r, r))
        for c in range(self.ChildConfigure.measureNum):
            led = MyLed()
            led.setEnabled(False)
            led.setChecked(True)
            # led.setText(str(r))
            led.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
            self.ledGroup.append(led)
            exec('self.boxLayout_{}.addWidget(led)'.format(r))
        exec('self.verticalLayout_3.addLayout(self.boxLayout_{})'.format(r))
    print(len(self.ledGroup))

四、led控件完整代码

PyQt4自定义控件----指示灯控件

你可能感兴趣的:(Python学习,python,qt,pycharm)