diff options
Diffstat (limited to 'gr-qtgui/python/qtgui/ledindicator.py')
-rw-r--r-- | gr-qtgui/python/qtgui/ledindicator.py | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/gr-qtgui/python/qtgui/ledindicator.py b/gr-qtgui/python/qtgui/ledindicator.py new file mode 100644 index 0000000000..09b2bd8e19 --- /dev/null +++ b/gr-qtgui/python/qtgui/ledindicator.py @@ -0,0 +1,197 @@ +#!/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) + |