def draw_span(self, painter, rect): opt = widgets.StyleOptionSlider() super().initStyleOption(opt) # area groove = self.style().subControlRect(SLIDER_STYLE, opt, GROOVE_STYLE, self) if opt.is_horizontal(): groove.adjust(0, 0, -1, 0) else: groove.adjust(0, 0, 0, -1) # pen & brush painter.setPen(gui.Pen(self.gradient_left, 0)) if opt.is_horizontal(): self.setup_painter(painter, opt.orientation, groove.center().x(), groove.top(), groove.center().x(), groove.bottom()) else: self.setup_painter(painter, opt.orientation, groove.left(), groove.center().y(), groove.right(), groove.center().y()) # draw groove intersected = core.RectF(rect.intersected(groove)) gradient = QtGui.QLinearGradient(intersected.topLeft(), intersected.topRight()) gradient.setColorAt(0, self.gradient_left) gradient.setColorAt(1, self.gradient_right) painter.fillRect(intersected, gradient)
def _draw_span(self, painter: widgets.StylePainter, rect: core.Rect): opt = widgets.StyleOptionSlider() self.initStyleOption(opt) painter.set_pen(color=self.gradient_left, width=0) groove = self.style().subControlRect(SLIDER_STYLE, opt, GROOVE_STYLE, self) if opt.is_horizontal(): groove.adjust(0, 0, -1, 0) self._setup_painter( painter, opt.get_orientation(), groove.center().x(), groove.top(), groove.center().x(), groove.bottom(), ) else: groove.adjust(0, 0, 0, -1) self._setup_painter( painter, opt.get_orientation(), groove.left(), groove.center().y(), groove.right(), groove.center().y(), ) # draw groove intersected = core.RectF(rect.intersected(groove)) gradient = gui.LinearGradient(intersected.topLeft(), intersected.topRight()) gradient[0] = self.gradient_left gradient[1] = self.gradient_right painter.fillRect(intersected, gradient)
def get_style_option(self, handle: HandleStr) -> widgets.StyleOptionSlider: option = widgets.StyleOptionSlider() self.initStyleOption(option) if handle == "lower": option.sliderPosition = self.lower_pos option.sliderValue = self.lower_val else: option.sliderPosition = self.upper_pos option.sliderValue = self.upper_val return option
def paintEvent(self, e): super().paintEvent(e) style = self.sl.style() st_slider = widgets.StyleOptionSlider() st_slider.initFrom(self.sl) st_slider.orientation = self.sl.orientation() length = style.pixelMetric( widgets.Style.PixelMetric.PM_SliderLength, st_slider, self.sl ) available = style.pixelMetric( widgets.Style.PixelMetric.PM_SliderSpaceAvailable, st_slider, self.sl ) painter = gui.Painter(self) for v, v_str in self.levels: # get the size of the label rect = painter.get_text_rect(v_str) if self.sl.is_horizontal(): x_loc = widgets.Style.sliderPositionFromValue( self.sl.minimum(), self.sl.maximum(), v, available ) # I assume the offset is half the length of slider, therefore # + length//2 x_loc += length // 2 # left bound of the text = center - half of text width + L_margin left = x_loc - rect.width() // 2 + self.left_margin bottom = self.rect().bottom() # enlarge margins if clipping if v == self.sl.minimum(): if left <= 0: self.left_margin = rect.width() // 2 - x_loc self.bottom_margin = max(self.bottom_margin, rect.height()) self.adjust_margins() if v == self.sl.maximum() and rect.width() // 2 >= self.right_margin: self.right_margin = rect.width() // 2 self.adjust_margins() else: y_loc = widgets.Style.sliderPositionFromValue( self.sl.minimum(), self.sl.maximum(), v, available, upsideDown=True ) bottom = y_loc + length // 2 + rect.height() // 2 + self.top_margin - 3 # there is a 3 px offset that I can't attribute to any metric left = self.left_margin - rect.width() if left <= 0: self.left_margin = rect.width() + 2 self.adjust_margins() painter.drawText(left, bottom, v_str)
def draw_handle(self, painter, handle): opt = widgets.StyleOptionSlider() self._initStyleOption(opt, handle) opt.subControls = HANDLE_STYLE pressed = self.upper_pressed if handle == self.LOWER_HANDLE: pressed = self.lower_pressed if pressed == HANDLE_STYLE: opt.activeSubControls = pressed opt.state |= widgets.Style.State_Sunken painter.drawComplexControl(SLIDER_STYLE, opt)
def mouseMoveEvent(self, event): if (self.lower_pressed != HANDLE_STYLE and self.upper_pressed != HANDLE_STYLE): event.ignore() return opt = widgets.StyleOptionSlider() self.initStyleOption(opt) m = self.style().pixelMetric(widgets.Style.PM_MaximumDragDistance, opt, self) new_pos = self.pixel_pos_to_value(self.pick(event.pos()) - self.offset) if m >= 0: r = self.rect().adjusted(-m, -m, m, m) if not r.contains(event.pos()): new_pos = self.position # pick the preferred handle on the first movement if self.first_movement: if self.lower == self.upper: if new_pos < self.lower_value: self.swap_controls() self.first_movement = False else: self.first_movement = False if self.lower_pressed == HANDLE_STYLE: if self.movement == "no_crossing": new_pos = min(new_pos, self.upper) elif self.movement == "no_overlap": new_pos = min(new_pos, self.upper - 1) if self.movement == "free" and new_pos > self.upper: self.swap_controls() self.set_upper_pos(new_pos) else: self.set_lower_pos(new_pos) elif self.upper_pressed == HANDLE_STYLE: if self.movement == "no_crossing": new_pos = max(new_pos, self.lower_value) elif self.movement == "no_overlap": new_pos = max(new_pos, self.lower_value + 1) if self.movement == "free" and new_pos < self.lower: self.swap_controls() self.set_lower_pos(new_pos) else: self.set_upper_pos(new_pos) event.accept()
def handle_mouse_press(self, pos, control, value, handle): opt = widgets.StyleOptionSlider() self._initStyleOption(opt, handle) old_control = control control = self.style().hitTestComplexControl(SLIDER_STYLE, opt, pos, self) sr = self.style().subControlRect(SLIDER_STYLE, opt, HANDLE_STYLE, self) if control == HANDLE_STYLE: self.position = value self.offset = self.pick(pos - sr.topLeft()) self.last_pressed = handle self.setSliderDown(True) self.slider_pressed.emit(handle) if control != old_control: self.update(sr) return control
def paintEvent(self, event): painter = widgets.StylePainter(self) # ticks opt = widgets.StyleOptionSlider() self.initStyleOption(opt) opt.subControls = widgets.Style.SubControl.SC_SliderTickmarks painter.draw_complex_control("slider", opt) # groove opt.sliderPosition = 20 opt.sliderValue = 0 opt.subControls = GROOVE_STYLE painter.draw_complex_control("slider", opt) # handle rects opt.sliderPosition = self.lower_pos lr = self.style().subControlRect(SLIDER_STYLE, opt, HANDLE_STYLE, self) lrv = self.pick(lr.center()) opt.sliderPosition = self.upper_pos ur = self.style().subControlRect(SLIDER_STYLE, opt, HANDLE_STYLE, self) urv = self.pick(ur.center()) # span minv = min(lrv, urv) maxv = max(lrv, urv) c = self.style().subControlRect(SLIDER_STYLE, opt, GROOVE_STYLE, self).center() if self.is_horizontal(): rect = core.Rect(core.Point(minv, c.y() - 2), core.Point(maxv, c.y() + 1)) else: rect = core.Rect(core.Point(c.x() - 2, minv), core.Point(c.x() + 1, maxv)) self._draw_span(painter, rect) # handles if self.last_pressed == "lower": self.draw_handle(painter, "upper") self.draw_handle(painter, "lower") else: self.draw_handle(painter, "lower") self.draw_handle(painter, "upper")
def pixel_pos_to_value(self, pos): opt = widgets.StyleOptionSlider() self.initStyleOption(opt) gr = self.style().subControlRect(SLIDER_STYLE, opt, GROOVE_STYLE, self) sr = self.style().subControlRect(SLIDER_STYLE, opt, HANDLE_STYLE, self) if self.is_horizontal(): len_slider = sr.width() slider_min = gr.x() slider_max = gr.right() - len_slider + 1 else: len_slider = sr.height() slider_min = gr.y() slider_max = gr.bottom() - len_slider + 1 return widgets.Style.sliderValueFromPosition(self.minimum(), self.maximum(), pos - slider_min, slider_max - slider_min, opt.upsideDown)
def test_styleoptionslider(): slider = widgets.StyleOptionSlider() slider.is_vertical() slider.set_horizontal() slider.set_vertical()