class ApolloLabeledSwitch(ApolloControl): def __init__(self, parent, text, lines=1, tristate=False, labelwidth=32, *args, **kwargs): super().__init__(parent, *args, **kwargs) # Make sure the text is bottom aligned in the specified number of lines text = "\n" * (lines - text.count("\n") - 1) + text self.label = QLabel(text, self) self.label.setFixedWidth(labelwidth) self.addWidget(self.label) self.layout.addSpacing(3) self.switch = QCheckBox(self) if tristate: self.switch.setTristate(True) self.switch.setFixedSize(20, 20) self.switch.setStyleSheet( 'QCheckBox::indicator{ subcontrol-position:center; } QCheckBox { color: #666; }' ) self.addWidget(self.switch) self.addStretch(100)
def _create_reg(self, frame, layout, col, width, cmp_switches, ign_switches, cmp_fn, ign_fn): # Add indicators for each bit in the register, from MSB to LSB for i in range(width, 0, -1): check = QCheckBox(frame) check.setFixedSize(20, 20) check.setStyleSheet( 'QCheckBox::indicator{subcontrol-position:center;}') check.stateChanged.connect(cmp_fn) layout.addWidget(check, 0, col) layout.setAlignment(check, Qt.AlignCenter) cmp_switches.append(check) check = QCheckBox(frame) check.setFixedSize(20, 20) check.setStyleSheet( 'QCheckBox::indicator{subcontrol-position:center;}') check.stateChanged.connect(ign_fn) layout.addWidget(check, 1, col) layout.setAlignment(check, Qt.AlignCenter) ign_switches.append(check) col += 1 # Add separators between each group of 3 bits if (i < 16) and (i > 1) and ((i % 3) == 1): sep = QFrame(frame) sep.setFrameStyle(QFrame.VLine | QFrame.Raised) layout.addWidget(sep, 0, col, 2, 1) col += 1 return col
def _create_status_lights(self, layout): # Create a frame to hold the register's bits status_frame = QFrame(self) layout.addWidget(status_frame) layout.setAlignment(status_frame, Qt.AlignBottom) status_layout = QGridLayout(status_frame) status_layout.setSpacing(0) status_layout.setMargin(0) status_frame.setLayout(status_layout) status_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised) # Add indicators for each status in the register, from MSB to LSB for col, stat in enumerate(STATUS_INDS.keys()): check = QCheckBox(status_frame) check.setFixedSize(30, 20) check.setStyleSheet( 'QCheckBox::indicator{subcontrol-position:center;}') check.stateChanged.connect(lambda state: self._update_status()) status_layout.addWidget(check, 0, col) status_layout.setAlignment(check, Qt.AlignCenter) self._status_cmp_switches[stat] = check check = QCheckBox(status_frame) check.setFixedSize(30, 20) check.setStyleSheet( 'QCheckBox::indicator{subcontrol-position:center;}') check.stateChanged.connect(lambda state: self._update_status()) status_layout.addWidget(check, 1, col) status_layout.setAlignment(check, Qt.AlignCenter) self._status_ign_switches[stat] = check
def paint(self, painter, option, index): checked = bool(index.data()) checkbox = QCheckBox() if (index.flags() & Qt.ItemIsEditable) > 0: checkbox.setEnabled(True) else: checkbox.setEnabled(False) # Implement tristate checkboxe for folder nodes if checked: checkbox.setCheckState(Qt.Checked) else: checkbox.setCheckState(Qt.Unchecked) if self.parent(): checkbox.setStyleSheet(self.parent().styleSheet()) width = option.widget.columnWidth(1) height = option.widget.rowHeight(0) painter.save() painter.translate(option.rect.topLeft()) checkbox.rect = option.rect checkbox.setFixedSize(width, height) checkbox.render(painter, QPoint(0, 0)) painter.restore()
def _create_inh_control(self, name, parent, layout, col): # Create a label for the inhibit switch label = QLabel(name, parent) label.setAlignment(Qt.AlignCenter) font = label.font() font.setPointSize(7) font.setBold(True) label.setFont(font) layout.addWidget(label, 0, col) # Add an indicator to show inhibit state ind = Indicator(parent, QColor(255, 120, 0)) ind.setFixedSize(20, 20) layout.addWidget(ind, 1, col) layout.setAlignment(ind, Qt.AlignCenter) # Add a switch to control the inhibit state check = QCheckBox(parent) check.setFixedSize(20, 20) check.setStyleSheet( 'QCheckBox::indicator{subcontrol-position:center;}') layout.addWidget(check, 2, col) layout.setAlignment(check, Qt.AlignCenter) layout.setColumnMinimumWidth(col, 25) self._inh_switches.append(check) self._inh_inds.append(ind)
def _add_switches(self, switch_frame, switch_layout, switches, switch_dict, switch_fn, row): col = 0 for v, l in switches.items(): check = QCheckBox(switch_frame) check.setFixedSize(20, 20) check.setStyleSheet( 'QCheckBox::indicator{subcontrol-position:center;}') check.stateChanged.connect(switch_fn) switch_dict[v] = check switch_layout.addWidget(check, row, col) switch_layout.setAlignment(check, Qt.AlignCenter) label = QLabel(l, switch_frame) font = label.font() font.setPointSize(7) font.setBold(True) label.setFont(font) switch_layout.addWidget(label, row + 1, col) switch_layout.setAlignment(label, Qt.AlignCenter) col += 1 if col >= 6: col = 0 row += 2 return row
def _create_stop_cond(self, label_text, name, layout, col): # Create an indicator to show stop status ind = Indicator(self, QColor(255, 0, 0)) ind.setFixedSize(25, 20) layout.addWidget(ind, 0, col) layout.setAlignment(ind, Qt.AlignCenter) self._stop_inds[name] = ind # Add a switch to control the stop control state check = QCheckBox(self) check.setFixedSize(20, 20) check.setStyleSheet( 'QCheckBox::indicator{subcontrol-position:center;}') layout.addWidget(check, 1, col) layout.setAlignment(check, Qt.AlignCenter) check.stateChanged.connect(self._set_stop_conds) self._stop_switches[name] = check # Create a label for the inhibit switch label = QLabel(label_text, self) label.setAlignment(Qt.AlignCenter) font = label.font() font.setPointSize(7) font.setBold(True) label.setFont(font) label_height = 2 if '\n' in label_text else 1 layout.addWidget(label, 2, col, label_height, 1) layout.setAlignment(label, Qt.AlignCenter | Qt.AlignTop)
def _create_bank_switch(self, name, layout, row, col, width): label = QLabel(name, self) label.setAlignment(Qt.AlignBottom | (Qt.AlignLeft if width == 2 else Qt.AlignCenter)) font = label.font() font.setPointSize(7) font.setBold(True) label.setFont(font) layout.addWidget(label, row, col, 1, width) check = QCheckBox(self) check.setFixedSize(20, 20) check.setStyleSheet( 'QCheckBox::indicator{subcontrol-position:center;}') layout.addWidget(check, row + 1, col, 1, 1) layout.setAlignment(check, Qt.AlignCenter) return check
class ApolloLabeledIndicatorSwitch(ApolloLabeledIndicator): def __init__(self, parent, text, color, lines=1, callback=None, direct_connect=True, *args, **kwargs): super().__init__(parent, text, color, lines, *args, **kwargs) self.switch = QCheckBox(self) if callback: self.switch.stateChanged.connect(callback) if direct_connect: self.switch.stateChanged.connect(self.indicator.set_on) self.switch.setFixedSize(20, 20) self.switch.setStyleSheet( 'QCheckBox::indicator{ subcontrol-position:center; } QCheckBox { color: #666; }' ) self.addWidget(self.switch) self.addStretch()
def _setup_ui(self): self.setFrameStyle(QFrame.StyledPanel | QFrame.Raised) layout = QGridLayout(self) self.setLayout(layout) layout.setMargin(1) layout.setSpacing(1) # Construct the alarm indicators col = 0 for n, c in ALARMS.items(): self._create_alarm(n, c, layout, col) col += 1 check = QCheckBox(self) check.setFixedSize(20, 20) check.setStyleSheet( 'QCheckBox::indicator{subcontrol-position:center;}') layout.addWidget(check, 2, 2) layout.setAlignment(check, Qt.AlignCenter) check.stateChanged.connect( lambda state: self._usbif.send(um.WriteControlDoscal(bool(state)))) check = QCheckBox(self) check.setFixedSize(20, 20) check.setStyleSheet( 'QCheckBox::indicator{subcontrol-position:center;}') layout.addWidget(check, 2, 3) layout.setAlignment(check, Qt.AlignCenter) check.stateChanged.connect( lambda state: self._usbif.send(um.WriteControlDbltst(bool(state)))) b = QPushButton(self) b.setFixedSize(20, 20) layout.addWidget(b, 2, 8, 1, 2) layout.setAlignment(b, Qt.AlignCenter) label = QLabel('RESET', self) label.setAlignment(Qt.AlignRight) font = label.font() font.setPointSize(8) font.setBold(True) label.setFont(font) label.setMinimumWidth(30) layout.addWidget(label, 2, 7, 1, 2) layout.setAlignment(label, Qt.AlignCenter) b.pressed.connect(lambda: self._reset_alarms()) label = QLabel('TEST', self) label.setAlignment(Qt.AlignRight) font = label.font() font.setPointSize(8) font.setBold(True) label.setFont(font) label.setMinimumWidth(30) layout.addWidget(label, 2, 1, 1, 1) layout.setAlignment(label, Qt.AlignRight) label = QLabel('ALARMS', self) font = label.font() font.setPointSize(12) font.setBold(True) label.setFont(font) label.setAlignment(Qt.AlignCenter) layout.addWidget(label, 2, len(ALARMS) - 4, 1, 4, Qt.AlignRight)
def _create_reg(self, width, cmp_switches, ign_switches): # Create a widget to hold the register's bits reg_widget = QWidget(self) reg_layout = QVBoxLayout(reg_widget) reg_widget.setLayout(reg_layout) reg_layout.setSpacing(0) reg_layout.setMargin(0) # Create a widget to hold the register's value and ignore textboxes values = QWidget(reg_widget) v_layout = QHBoxLayout(values) values.setLayout(v_layout) v_layout.setSpacing(1) v_layout.setMargin(0) reg_layout.addWidget(values) reg_layout.setAlignment(values, Qt.AlignRight) # Create textboxes to show the register's value and ignore mask in octal n_digits = int((width + 2) / 3) if n_digits == 1: value_width = 25 elif n_digits == 2: value_width = 30 else: value_width = 45 reg_value = QLineEdit(values) reg_value.setMaximumSize(value_width, 32) reg_value.setText(n_digits * '0') reg_value.setAlignment(Qt.AlignCenter) reg_value.setValidator(RegValidator(2**width - 1)) reg_value.setMaxLength(n_digits) reg_value.returnPressed.connect( lambda b=reg_value, s=cmp_switches: self._update_switches(b, s)) v_layout.addWidget(reg_value) ign_value = QLineEdit(values) ign_value.setMaximumSize(value_width, 32) ign_value.setText(n_digits * '0') ign_value.setAlignment(Qt.AlignCenter) ign_value.setValidator(RegValidator(2**width - 1)) ign_value.setMaxLength(n_digits) ign_value.returnPressed.connect( lambda b=ign_value, s=ign_switches: self._update_switches(b, s)) v_layout.addWidget(ign_value) font = QFont('Monospace') font.setStyleHint(QFont.TypeWriter) font.setPointSize(10) reg_value.setFont(font) ign_value.setFont(font) # Create a frame to hold the register's bits bit_frame = QFrame(reg_widget) bit_layout = QGridLayout(bit_frame) bit_layout.setSpacing(1) bit_layout.setMargin(0) bit_frame.setLayout(bit_layout) bit_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised) # Add indicators for each bit in the register, from MSB to LSB col = 0 for i in range(width, 0, -1): check = QCheckBox(bit_frame) check.setFixedSize(20, 20) check.setStyleSheet( 'QCheckBox::indicator{subcontrol-position:center;}') check.stateChanged.connect( lambda state, b=reg_value, s=cmp_switches: self. _update_reg_box(state, b, s)) bit_layout.addWidget(check, 0, col) bit_layout.setAlignment(check, Qt.AlignCenter) cmp_switches.append(check) check = QCheckBox(bit_frame) check.setFixedSize(20, 20) check.setStyleSheet( 'QCheckBox::indicator{subcontrol-position:center;}') check.stateChanged.connect( lambda state, b=ign_value, s=ign_switches: self. _update_reg_box(state, b, s)) bit_layout.addWidget(check, 1, col) bit_layout.setAlignment(check, Qt.AlignCenter) ign_switches.append(check) col += 1 # Add separators between each group of 3 bits if (i > 1) and ((i % 3) == 1): sep = QFrame(bit_frame) sep.setFrameStyle(QFrame.VLine | QFrame.Raised) bit_layout.addWidget(sep, 0, col, 2, 1) col += 1 reg_layout.addWidget(bit_frame) return reg_widget, reg_value, ign_value
def _setup_ui(self): self.setStyleSheet("QFrame { color: #666; }") layout = QVBoxLayout(self) self.setLayout(layout) layout.setMargin(0) layout.setSpacing(0) if self.include_values: # Value boxes vw = QWidget(self) vl = QHBoxLayout() vl.setSpacing(2) vl.setContentsMargins(0, 0, 0, 2) vw.setLayout(vl) layout.addWidget(vw) layout.setAlignment(vw, Qt.AlignRight) # Create textboxes to show the register's value and ignore mask in octal n_digits = int((self.width + 2) / 3) if n_digits == 1: value_width = 25 elif n_digits == 2: value_width = 30 else: value_width = 45 self.reg_box = QLineEdit(vw) self.reg_box.setFixedSize(value_width, 32) self.reg_box.setText(n_digits * '0') self.reg_box.setAlignment(Qt.AlignCenter) self.reg_box.setValidator(OctalValidator(2**self.width - 1)) self.reg_box.setMaxLength(n_digits) self.reg_box.returnPressed.connect(self._update_reg_switches) vl.addWidget(self.reg_box) self.ign_box = QLineEdit(vw) self.ign_box.setMaximumSize(value_width, 32) self.ign_box.setText(n_digits * '0') self.ign_box.setAlignment(Qt.AlignCenter) self.ign_box.setValidator(OctalValidator(2**self.width - 1)) self.ign_box.setMaxLength(n_digits) self.ign_box.returnPressed.connect(self._update_ign_switches) vl.addWidget(self.ign_box) # Switches ssf = QFrame(self) ssf.setFrameStyle(QFrame.Panel | QFrame.Plain) ssf.setStyleSheet( 'QCheckBox::indicator { subcontrol-position: center; }') ssl = QHBoxLayout() ssl.setSpacing(1) ssl.setContentsMargins(1, 0, 2, 0) ssf.setLayout(ssl) layout.addWidget(ssf) layout.setAlignment(ssf, Qt.AlignRight) for i in range(self.width, 0, -1): sw = QWidget(ssf) sl = QVBoxLayout() sl.setSpacing(1) sl.setContentsMargins(0, 1, 0, 1) sw.setLayout(sl) s1 = QCheckBox(sw) s1.setFixedSize(self.item_width, 20) sl.addWidget(s1) sl.setAlignment(s1, Qt.AlignCenter) s1.stateChanged.connect(self._update_reg_value) self._reg_switches.insert(0, s1) s2 = QCheckBox(sw) s2.setFixedSize(self.item_width, 20) sl.addWidget(s2) sl.setAlignment(s2, Qt.AlignCenter) s2.stateChanged.connect(self._update_ign_value) self._ign_switches.insert(0, s2) ssl.addWidget(sw) # Add separators between each group of 3 bits if self.separators and i in [17, 13, 10, 7, 4]: sep = QFrame(ssf) sep.setFrameStyle(QFrame.VLine | QFrame.Plain) ssl.addWidget(sep)