class HeaterEditor(QGroupBox): def __init__(self, controller, heater_type=None, parent=None): super(HeaterEditor, self).__init__(controller.label, parent) self.controller = controller # Determine min and max values max_volt = self.controller.board.get_volt_max() max_current = self.controller.board.get_heater_current_max() print("max_current: ", max_current) volt_setp_max_curr = self.controller.board.current2volt_setp(self.controller.channel, max_current) volt_setp_max = volt_setp_max_curr if max_volt > volt_setp_max_curr else max_volt print("max_volt: ", max_volt, "volt_setp_max_curr: ", volt_setp_max_curr, "volt_setp_max: ", volt_setp_max) pwr_max = np.round(self.controller.board.volt_setp2pwr(self.controller.channel, volt_setp_max)) pwr_min = self.controller.board.volt_setp2pwr(self.controller.channel, 0) # Heater settings dialogBox self.settings_button = QPushButton('Settings') self.active_heater = HeaterSettings(self.controller, volt_setp_max, pwr_max, heater_type) self.active_heater_window = HeaterSettingsWidget(self.active_heater) self.active_heater_window.setMinimumSize(250, 400) # self.active_heater_window.setBaseSize(600, 200) # Sliders # DoubleEditor(minval, maxval, stepsize) self.volt_setp_edit = DoubleEditor(0, self.active_heater.volt_limit.value(), .001) self.pwr_edit = DoubleEditor(pwr_min, self.active_heater.power_limit.value(), .001) # Indicators # IndicatorDouble(begin_value, min_value, max_value, decimals, unit_string) self.volt_setp_ind = IndicatorDouble(0., 0., self.active_heater.volt_limit.value(), 3, 'V') self.volt_pwr_ind = IndicatorDouble(0., 0., self.active_heater.volt_limit.value(), 3, 'V') # Layout self.sublayout = QGridLayout() self.sublayout.addWidget(self.volt_setp_edit, 0, 0) self.sublayout.addWidget(self.pwr_edit, 0, 1) self.sublayout.addWidget(self.volt_setp_ind, 1, 0) self.sublayout.addWidget(self.volt_pwr_ind, 1, 1) self.sublayout.addWidget(self.settings_button, 2, 0, 1, 2) self.setLayout(self.sublayout) # Signals and slots self.volt_setp_edit.slider.doubleValueChanged.connect(self.controller.set_value) self.volt_setp_edit.slider.doubleValueChanged.connect(self.update_pwr) self.pwr_edit.slider.doubleValueChanged.connect(self.update_voltage) self.settings_button.clicked.connect(self.active_heater_window.show) # connect heater settings. self.active_heater.volt_limit.edit.valueChanged.connect(self._update_range) self.active_heater.power_limit.edit.valueChanged.connect(self._update_range) def update_pwr(self, volt_setp): volt_pwr_ind = self.controller.board.volt_setp2volt(self.controller.channel, volt_setp) pwr = self.controller.board.volt_setp2pwr(self.controller.channel, volt_setp) # Update Indicators self.volt_setp_ind.setValue(volt_setp) self.volt_pwr_ind.setValue(volt_pwr_ind) # Update power self.pwr_edit.slider.setValue(pwr) @Slot(float) def update_voltage(self, value): # print("Value_uv:", value) self.volt_setp_edit.slider.setValue(self.controller.board.pwr2volt_setp(self.controller.channel, value)) @Slot() def _update_range(self): # update Sliders self.volt_setp_edit.set_range(0, self.active_heater.volt_limit.value()) self.pwr_edit.set_range(0., self.active_heater.power_limit.value()) # update Indicators self.volt_setp_ind.setRange(0., self.active_heater.volt_limit.value()) self.volt_pwr_ind.setRange(0., self.active_heater.volt_limit.value()) # update layouts self.sublayout.update() self.update()
class SerialDevicesGui(QWidget): def __init__(self): super().__init__() self.serial_device_list = [] self.current_serial_device = None self.monotonic_device_num = 0 self.layout = QGridLayout() self._setup() self.setLayout(self.layout) def update_device_list(self): self.serial_devices.clear() device_names = [d.name for d in self.serial_device_list] self.serial_devices.addItems(device_names) if len(self.serial_device_list) == 0: self.new_device() self.set_device(self.current_serial_device) def new_device(self): new_device = SerialDeviceGui(self, f"device_{self.monotonic_device_num}") self.serial_device_list.append(new_device) self.current_serial_device = new_device self.monotonic_device_num += 1 self.update_device_list() def remove_device(self, device): self.serial_device_list.remove(device) self.layout.removeWidget(device) device.setParent(None) self.layout.update() self.update_device_list() def set_device(self, device): if len(self.serial_device_list) > 1: self.layout.removeWidget(self.current_serial_device) self.current_serial_device.setParent(None) self.current_serial_device = device self.layout.addWidget(device, 2, 0, -1, -1) self.layout.update() def select_device(self): device = self.serial_devices.currentText() for d in self.serial_device_list: if d.name == device: self.set_device(d) def _setup(self): new_device = QPushButton("New Device") new_device.clicked.connect(self.new_device) self.serial_devices = QComboBox() self.serial_devices.setInsertPolicy(QComboBox.InsertAtBottom) self.serial_devices.currentIndexChanged.connect(self.select_device) n = 0 self.layout.addWidget(new_device, n, 0, 1, 1) n += 1 self.layout.addWidget(self.serial_devices, n, 0, 1, 1) self.new_device()
class DoubleEditor(QWidget): """ Taken from https://gist.github.com/dennis-tra/994a65d6165a328d4eabaadbaedac2cc ▲▼ Slider DoubleEditor is based on QWidget and gives a combination of a QDoubleSpinBox() and (own) DoubleSlider with appropiate minima, maxima and stepsizes and which, above all, are synchronized. """ def __init__(self, minval, maxval, stepsize=.1, parent=None): super(DoubleEditor, self).__init__(parent) # Edit field self.maxval = maxval self.minval = minval # print("self.maxval: ", self.maxval) self.edit = QDoubleSpinBox(self) self.edit.setKeyboardTracking(False) self.edit.setRange(self.minval, self.maxval) self.edit.setSingleStep(stepsize) self.edit.setMinimumWidth(70) if stepsize < 1.: decimals = int(np.ceil(-np.log10(stepsize))) else: decimals = 1 self.edit.setDecimals(decimals) # Slider self.slider = DoubleSlider(min_val=self.minval, max_val=self.maxval, stepsize=stepsize, orientation=Qt.Vertical, parent=self) self.slider.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding) # Ticks self.q_ticks = QSlider.TicksBelow self.slider.setTickPosition(self.q_ticks) self.tick_amount = 6 self.slider_range = self.slider.maximum() - self.slider.minimum() self.tick_interval = int(round(self.slider_range / (self.tick_amount-1))) self.slider.setTickInterval(self.tick_interval) # ...labels font = QFont() font.setPointSize(8) self.tick_str1 = QLabel('{:.0f}'.format(self.minval), self) self.tick_str2 = QLabel('{:.0f}'.format(self.maxval), self) self.tick_str1.setFont(font) self.tick_str2.setFont(font) self.slider_tick_layout = QGridLayout() self.tick_str1.setAlignment(Qt.AlignBottom | Qt.AlignLeft) self.tick_str2.setAlignment(Qt.AlignTop | Qt.AlignLeft) self.slider_tick_layout.addWidget(self.slider, 0, 0, self.tick_amount, 1) self.slider_tick_layout.addWidget(self.tick_str2, 0, 1, 1, 1) self.slider_tick_layout.addWidget(self.tick_str1, self.tick_amount - 1, 1, 1, 1) # Layout self.layout = QVBoxLayout() self.layout.addLayout(self.slider_tick_layout) self.layout.addWidget(self.edit) self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding) self.setLayout(self.layout) # Signals and slots self.edit.valueChanged.connect(self.slider.setValue) self.slider.doubleValueChanged.connect(self.edit.setValue) @Slot(float) def set_range(self, min, max): # update min and max values self.minval = min self.maxval = max # set new range for spinbox and slider self.edit.setRange(self.minval, self.maxval) self.slider.set_range(self.minval, self.maxval) # calculate and set new slider ranges self.slider.setTickPosition(self.q_ticks) self.slider_range = self.slider.maximum() - self.slider.minimum() self.tick_interval = int(round(self.slider_range / (self.tick_amount - 1))) self.slider.setTickInterval(self.tick_interval) # change slider min max values self.tick_str1.setText('{:.0f}'.format(self.minval)) self.tick_str2.setText('{:.0f}'.format(self.maxval)) # update widgets and layouts self.edit.update() self.slider.update() self.slider_tick_layout.update() self.layout.update() self.update()