def __init__(self, parent=None, cutoff_value=0.01, limit_type="percent"): super().__init__(parent) self.cutoff_value = cutoff_value self.limit_type = limit_type locale = QLocale(QLocale.English, QLocale.UnitedStates) locale.setNumberOptions(QLocale.RejectGroupSeparator) self.validators = Types(QDoubleValidator(0.001, 100.0, 1, self), QIntValidator(0, 50, self)) self.validators.relative.setLocale(locale) self.validators.topx.setLocale(locale) self.buttons = Types(QRadioButton("Relative"), QRadioButton("Top #")) self.buttons.relative.setChecked(True) self.buttons.relative.setToolTip( "This cut-off type shows the selected top percentage of contributions (for example the \ top 10% contributors)") self.buttons.topx.setToolTip( "This cut-off type shows the selected top number of contributions (for example the top \ 5 contributors)") self.button_group = QButtonGroup() self.button_group.addButton(self.buttons.relative, 0) self.button_group.addButton(self.buttons.topx, 1) self.sliders = Types(LogarithmicSlider(self), QSlider(Qt.Horizontal, self)) self.sliders.relative.setToolTip( "This slider sets the selected percentage of contributions\ to be shown") self.sliders.topx.setToolTip( "This slider sets the selected number of contributions to be \ shown") self.units = Types("% of total", "top #") self.labels = Labels(QLabel(), QLabel(), QLabel()) self.cutoff_slider_line = QLineEdit() self.cutoff_slider_line.setToolTip( "This box can set a precise cut-off value for the \ contributions to be shown") self.cutoff_slider_line.setLocale(locale) self.cutoff_slider_lft_btn = QPushButton("<") self.cutoff_slider_lft_btn.setToolTip( "This button moves the cut-off value one increment") self.cutoff_slider_rght_btn = QPushButton(">") self.cutoff_slider_rght_btn.setToolTip( "This button moves the cut-off value one increment") self.make_layout() self.connect_signals()
class SliderBar(QWidget): value_changed = Signal(float) def __init__(self, title: str = '', value: float = 0, min_value: float = 0, max_value: float = 100, displayed_value_factor: float = 1, parent: QWidget = None): super().__init__(parent) self._value = value self._min_value = min_value self._max_value = max_value self._displayed_value_factor = displayed_value_factor self._title_label = QLabel(title) self._color = DEFAULT_BAR_COLOR self._locale = QLocale(QLocale.English) self._locale.setNumberOptions(self._locale.numberOptions() | QLocale.RejectGroupSeparator) validator = QDoubleValidator(self._min_value, self._max_value, 2) validator.setNotation(QDoubleValidator.StandardNotation) validator.setLocale(self._locale) self._value_line_edit = SliderValueLineEdit() self._value_line_edit.setValidator(validator) max_label_width = self._value_line_edit.fontMetrics().width( self._value_to_str(self.max_value)) self._value_line_edit.setFixedWidth(6 + max_label_width) self._value_line_edit.editingFinished.connect( self._on_value_line_edit_editing_finished) h_layout = QHBoxLayout(self) h_layout.setContentsMargins(4, 0, 4, 0) # h_layout.setSpacing(0) h_layout.addWidget(self._title_label, 0, Qt.AlignLeft) h_layout.addWidget(self._value_line_edit, 0, Qt.AlignRight) self._update_value_line_edit() @property def title(self) -> str: return self._title_label.text() @title.setter def title(self, value: str): self._title_label.setText(value) @property def value(self) -> float: return self._value @value.setter def value(self, value: float): value = max(min(value, self._max_value), self._min_value) if self._value != value: self._value = value self._update_value_line_edit() self.update() self.value_changed.emit(self._value) @property def min_value(self) -> float: return self._min_value @min_value.setter def min_value(self, value: float): if self._min_value != value: self._min_value = value if self.value < self._min_value: self.value = self._min_value else: self.update() @property def max_value(self) -> float: return self._max_value @max_value.setter def max_value(self, value: float): if self._max_value != value: self._max_value = value if self.value > self._max_value: self.value = self._max_value else: self.update() @property def color(self) -> QColor: return self._color @color.setter def color(self, value: QColor): if self._color != value: self._color = value self.update() @property def font_height(self): return self._title_label.fontMetrics().height() def set_focus(self): self._value_line_edit.setFocus() def increase_value(self, factor: float = 1): self.change_value_by_delta(1 * factor) def decrease_value(self, factor: float = 1): self.change_value_by_delta(-1 * factor) def change_value_by_delta(self, delta: float): self.value += delta self._value_line_edit.selectAll() def paintEvent(self, event: QPaintEvent): super().paintEvent(event) painter = QPainter(self) painter.setPen(Qt.NoPen) painter.setBrush(self.color) painter.drawRect( 0, 0, round((self._value - self._min_value) / (self._max_value - self._min_value) * self.width()), self.height()) def mouseMoveEvent(self, event: QMouseEvent): self._update_value_by_x(event.x()) event.accept() def mousePressEvent(self, event: QMouseEvent): self.set_focus() self._update_value_by_x(event.x()) event.accept() def mouseDoubleClickEvent(self, event: QMouseEvent): self._value_line_edit.selectAll() event.accept() def keyPressEvent(self, event: QKeyEvent): if event.key() == Qt.Key_Up: self.increase_value() elif event.key() == Qt.Key_Down: self.decrease_value() elif event.key() == Qt.Key_PageUp: self.increase_value(10) elif event.key() == Qt.Key_PageDown: self.decrease_value(10) def wheelEvent(self, event: QWheelEvent): value_delta = event.angleDelta().y() / 120 if event.modifiers() & Qt.ControlModifier: value_delta *= 10 self.set_focus() self.increase_value(value_delta) event.accept() def _on_value_line_edit_editing_finished(self): self.value, ok = self._locale.toFloat(self._value_line_edit.text()) def _update_value_by_x(self, x: int): self.value = (self.max_value - self.min_value) * x / self.width() + self.min_value def _update_value_line_edit(self): self._value_line_edit.setText(self._value_to_str(self.value)) def _value_to_str(self, value: float) -> str: return self._locale.toString( float(value * self._displayed_value_factor), 'f', 2)