#!/usr/bin/env python # -*- coding: utf-8 -*- # # Copyright 2020 Free Software Foundation, Inc. # # This file is part of GNU Radio # # SPDX-License-Identifier: GPL-3.0-or-later # # from PyQt5.QtWidgets import QFrame, QHBoxLayout, QVBoxLayout, QLabel from PyQt5.QtGui import QPainter, QBrush, QColor, QPen, QFontMetricsF from PyQt5.QtCore import Qt as Qtc from PyQt5.QtCore import QPoint from PyQt5.QtGui import QRadialGradient from gnuradio import gr import pmt class LabeledLEDIndicator(QFrame): # Positions: 1 = above, 2=below, 3=left, 4=right def __init__(self, lbl='', onColor='green', offColor='red', initialState=False, maxSize=80, position=1, alignment=1, valignment=1, parent=None): QFrame.__init__(self, parent) self.numberControl = LEDIndicator( onColor, offColor, initialState, maxSize, parent) if position < 3: layout = QVBoxLayout() else: layout = QHBoxLayout() if not lbl: lbl = " " self.lbl = lbl self.lblcontrol = QLabel(lbl, self) self.lblcontrol.setAlignment(Qtc.AlignCenter) # add top or left if len: if position == 1 or position == 3: layout.addWidget(self.lblcontrol) else: self.hasLabel = False layout.addWidget(self.numberControl) # Add bottom or right if len: if position == 2 or position == 4: layout.addWidget(self.lblcontrol) if alignment == 1: halign = Qtc.AlignCenter elif alignment == 2: halign = Qtc.AlignLeft else: halign = Qtc.AlignRight if valignment == 1: valign = Qtc.AlignVCenter elif valignment == 2: valign = Qtc.AlignTop else: valign = Qtc.AlignBottom layout.setAlignment(halign | valign) self.setLayout(layout) if len: textfont = self.lblcontrol.font() metrics = QFontMetricsF(textfont) maxWidth = max((maxSize + 30), (maxSize + metrics.width(lbl) + 4)) maxHeight = max((maxSize + 35), (maxSize + metrics.height() + 2)) self.setMinimumSize(maxWidth, maxHeight) else: self.setMinimumSize(maxSize + 2, maxSize + 2) self.show() def setState(self, on_off): self.numberControl.setState(on_off) class LEDIndicator(QFrame): def __init__(self, onColor='green', offColor='red', initialState=False, maxSize=80, parent=None): QFrame.__init__(self, parent) self.maxSize = maxSize self.curState = initialState self.on_color = QColor(onColor) self.off_color = QColor(offColor) self.setMinimumSize(maxSize, maxSize) self.setMaximumSize(maxSize, maxSize) def setState(self, on_off): self.curState = on_off super().update() def paintEvent(self, event): super().paintEvent(event) painter = QPainter(self) size = self.size() brush = QBrush() smallest_dim = size.width() if smallest_dim > size.height(): smallest_dim = size.height() smallest_dim = smallest_dim / 2 smallest_dim -= 2 center_x = size.width() / 2 center_y = size.height() / 2 centerpoint = QPoint(center_x, center_y) radius = smallest_dim painter.setPen(QPen(QColor('lightgray'), 0)) brush.setStyle(Qtc.SolidPattern) radial = QRadialGradient(center_x, center_y / 2, radius) radial.setColorAt(0, Qtc.white) radial.setColorAt(0.8, Qtc.darkGray) painter.setBrush(QBrush(radial)) painter.drawEllipse(centerpoint, radius, radius) # Draw the colored center radial = QRadialGradient(center_x, center_y / 2, radius) radial.setColorAt(0, Qtc.white) if self.curState: radial.setColorAt(.7, self.on_color) brush.setColor(self.on_color) painter.setPen(QPen(self.on_color, 0)) else: radial.setColorAt(.7, self.off_color) brush.setColor(self.off_color) painter.setPen(QPen(self.off_color, 0)) brush.setStyle(Qtc.SolidPattern) painter.setBrush(QBrush(radial)) if smallest_dim <= 30: radius = radius - 3 elif smallest_dim <= 60: radius = radius - 4 elif smallest_dim <= 100: radius = radius - 5 elif smallest_dim <= 200: radius = radius - 6 elif smallest_dim <= 300: radius = radius - 7 else: radius = radius - 9 painter.drawEllipse(centerpoint, radius, radius) class GrLEDIndicator(gr.sync_block, LabeledLEDIndicator): """ This block makes a basic LED indicator """ def __init__(self, lbl='', onColor='green', offColor='red', initialState=False, maxSize=80, position=1, alignment=1, valignment=1, parent=None): gr.sync_block.__init__(self, name="LEDIndicator", in_sig=None, out_sig=None) LabeledLEDIndicator.__init__(self, lbl, onColor, offColor, initialState, maxSize, position, alignment, valignment, parent) self.lbl = lbl self.message_port_register_in(pmt.intern("state")) self.set_msg_handler(pmt.intern("state"), self.msgHandler) def msgHandler(self, msg): try: new_val = pmt.to_python(pmt.cdr(msg)) if type(new_val) == bool or type(new_val) == int: if type(new_val) == bool: super().setState(new_val) else: if new_val == 1: super().setState(True) else: super().setState(False) else: gr.log.error( "Value received was not an int or a bool: %s" % str(type(new_val))) except Exception as e: gr.log.error("Error with message conversion: %s" % str(e)) def setState(self, on_off): super().setState(on_off)