Example #1
0
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()
Example #3
0
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()