from typing import (
Dict
)
import asyncio
import serial
from qasync import (
asyncSlot
)
from rfblocks import (
pe43711, PE43711Controller, create_serial, write_cmd
)
from PyQt5.QtWidgets import (
QGroupBox, QVBoxLayout, QHBoxLayout, QFormLayout, QButtonGroup,
QRadioButton, QLabel, QDoubleSpinBox, QPushButton, QCheckBox,
QMessageBox, QErrorMessage, QWidget, QLineEdit, QDialog,
QComboBox, QSpinBox, QDialogButtonBox, QFileDialog
)
from PyQt5.QtCore import (
Qt, pyqtSignal, pyqtSlot, QObject
)
[docs]class StepAttenuator(QObject):
def __init__(self,
app: QWidget,
controller: PE43711Controller) -> None:
"""
"""
super().__init__()
self._app: QWidget = app
self._controller: PE43711Controller = controller
self._group_box = None
@property
def ctl(self) -> PE43711Controller:
return self._controller
@property
def enabled(self) -> bool:
"""Enable/disable the on screen attenuator UI components.
"""
if self._group_box:
return self._group_box.isEnabled()
else:
return False
@enabled.setter
def enabled(self, en: bool) -> None:
if self._group_box:
self._group_box.setEnabled(en)
def disable_controls(self, f):
if self._group_box:
self._group_box.setDisabled(f)
def set_attenuation(self, a):
self.ctl.attenuation = a
def update_attenuation(self, a):
self._atten_box.setValue(a)
def showErrorMessage(self, msg):
error_dialog = QErrorMessage(self._app)
error_dialog.setWindowModality(Qt.WindowModal)
error_dialog.setParent(self._app, Qt.Sheet)
error_dialog.setResult(0)
error_dialog.showMessage(msg)
[docs] def dump_config(self) -> Dict:
"""Return the current configuration for this attenuator module.
:return: A dictionary containing the current attenuator module
configuration.
"""
return self.ctl.dump_config()
[docs] def load_config(self, config: Dict) -> None:
"""Set the current configuration for this attenuator module.
:param config: A dictionary containing the attenuator configuration
to be set.
:type config: Dict
"""
self.ctl.load_config(config)
[docs] def initialize_hw(self, ser: serial.Serial) -> None:
"""Initialize the attenuator board hardware.
"""
_ = self.ctl.initialize(ser)
def initialize_ui(self):
self._atten_box.setValue(pe43711.MAX_ATTENUATION)
def configure_ui(self, config: Dict) -> None:
self._atten_box.setValue(config['atten'])
@asyncSlot()
async def config_attenuation(self):
try:
with create_serial(self._app.ctl_device,
self._app.baudrate) as ser:
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, self.ctl.configure, ser)
except serial.serialutil.SerialException as se:
self.showErrorMessage(str(se))
def create_attenuator_group(
self,
has_configure: bool = True) -> QGroupBox:
self._group_box = QGroupBox("{} Attenuator:".format(
self.ctl._controller_id))
self._group_box.setLayout(
self.create_attenuator_layout(has_configure))
return self._group_box
[docs] def create_attenuator_layout(
self,
has_configure: bool = True) -> QVBoxLayout:
"""Create UI controls for a PE43711 step attenuator board.
"""
vbox = QVBoxLayout()
fbox = QFormLayout()
hbox = QHBoxLayout()
self._atten_box = QDoubleSpinBox()
self._atten_box.setStyleSheet("""QDoubleSpinBox {
font-size: 25pt; }""")
self._atten_box.setSuffix(" dB")
self._atten_box.setRange(pe43711.MIN_ATTENUATION,
pe43711.MAX_ATTENUATION)
self._atten_box.setSingleStep(pe43711.STEP_SIZE)
self._atten_box.valueChanged.connect(self.set_attenuation)
self._atten_box.setValue(pe43711.MAX_ATTENUATION)
fbox.addRow(QLabel("Attenuation:"), self._atten_box)
self.ctl.attenuation_changed.connect(self.update_attenuation)
hbox.addLayout(fbox)
hbox.addStretch()
vbox.addLayout(hbox)
if has_configure is True:
hbox = QHBoxLayout()
set_atten_btn = QPushButton("Configure")
set_atten_btn.clicked.connect(self.config_attenuation)
hbox.addStretch()
hbox.addWidget(set_atten_btn)
vbox.addLayout(hbox)
return vbox