Beispiel #1
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()