一、效果图
1.1 指示灯效果图
1.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))