def mousePressEvent(self, event): """ Handle the mouse press event for the control. In a typical slider control, when the user clicks on a point in the slider's total range but not on the thumbtrack, the control would jump to the value of the click location. For this control, clicks which are not direct hits will activate both slider handles for synchronized moving. """ if event.button() != Qt.LeftButton: event.ignore() return event.accept() style = self.style() pos = event.pos() opt = QStyleOptionSlider() self.initStyleOption(opt) low, high = self._low, self._high # hit-test the high handle opt.sliderPosition = high high_rect = style.subControlRect( style.CC_Slider, opt, style.SC_SliderHandle, self ) high_test = high_rect.contains(pos) # hit-test the low handle if needed. if high_test: low_test = False else: opt.sliderPosition = low low_rect = style.subControlRect( style.CC_Slider, opt, style.SC_SliderHandle, self ) low_test = low_rect.contains(pos) # Set the internal state for painting and request an update. # The click offsets when clicking a thumbtrack are stored in # units of pixels. The offset for a click in the empty slider # area is stored in units of value. self._pressed_control = style.SC_SliderHandle if high_test: self._active_thumb = self.HighThumb self._click_offset = self._pick(pos - high_rect.topLeft()) elif low_test: self._active_thumb = self.LowThumb self._click_offset = self._pick(pos - low_rect.topLeft()) else: self._active_thumb = self.BothThumbs offset = self._pixelPosToRangeValue(self._pick(pos), opt) self._click_offset = offset self.setSliderDown(True) self.update()
def paintEvent(self, event): # based on # https://github.com/qt/qtbase/blob/f40dbe0d0b54ce83d2168e82905cf4f75059a841/src/widgets/widgets/qslider.cpp#L315 # https://github.com/enthought/traitsui/blob/master/traitsui/qt4/extra/range_slider.py painter = QStylePainter(self) minpos = self.__min_position maxpos = self.__max_position # Draw the groove opt = QStyleOptionSlider() self.initStyleOption(opt) # Draw empty grove opt.sliderPosition = opt.minimum opt.subControls = QStyle.SC_SliderGroove if self.tickPosition() != self.NoTicks: opt.subControls |= QStyle.SC_SliderTickmarks painter.drawComplexControl(QStyle.CC_Slider, opt) # Draw the highlighted part on top # Qt4.8 and Qt5.3 draw the highlighted groove in a weird way because they # transpose opt.rect. Qt5.7 works fine. if QT_VERSION_STR >= '5.7.0': opt.subControls = QStyle.SC_SliderGroove opt.sliderPosition = opt.maximum if self.orientation() == Qt.Horizontal: _w = opt.rect.width() / opt.maximum x = round(_w * minpos) w = round(_w * (maxpos - minpos)) opt.rect = QRect(x, 0, w, opt.rect.height()) else: _h = opt.rect.height() / opt.maximum y = round(_h * minpos) h = round(_h * (maxpos - minpos)) opt.rect = QRect(0, y, opt.rect.width(), h) painter.drawComplexControl(QStyle.CC_Slider, opt) # Draw the handles for i, position in enumerate((minpos, maxpos)): opt = QStyleOptionSlider() self.initStyleOption(opt) opt.subControls = QStyle.SC_SliderHandle if self.__pressed_control and (self.__active_slider == i or self.__active_slider < 0): opt.activeSubControls = self.__pressed_control opt.state |= QStyle.State_Sunken else: opt.activeSubControls = self.__hovered_control opt.sliderPosition = position opt.sliderValue = position painter.drawComplexControl(QStyle.CC_Slider, opt)
def mousePressEvent(self, event): if not event.button(): event.ignore() return event.accept() opt = QStyleOptionSlider() self.initStyleOption(opt) self.__active_slider = -1 for i, value in enumerate((self.__min_position, self.__max_position)): opt.sliderPosition = value if self._hitTestHandle(opt, event.pos()): self.__active_slider = i self.__pressed_control = QStyle.SC_SliderHandle self.triggerAction(self.SliderMove) self.setRepeatAction(self.SliderNoAction) self.setSliderDown(True) break else: # If the user clicks the groove between the handles, the whole # interval is moved self.__pressed_control = QStyle.SC_SliderGroove self.__click_offset = self._pixelPosToRangeValue(self._pick(event.pos())) self.triggerAction(self.SliderMove) self.setRepeatAction(self.SliderNoAction)
def paintEvent(self, event): painter = QStylePainter(self) # ticks opt = QStyleOptionSlider() self.initStyleOption(opt) opt.subControls = QStyle.SC_SliderTickmarks painter.drawComplexControl(QStyle.CC_Slider, opt) # groove opt.sliderPosition = 20 opt.sliderValue = 0 opt.subControls = QStyle.SC_SliderGroove painter.drawComplexControl(QStyle.CC_Slider, opt) # handle rects opt.sliderPosition = self.lowerPos lr = self.style().subControlRect(QStyle.CC_Slider, opt, QStyle.SC_SliderHandle, self) lrv = self.pick(lr.center()) opt.sliderPosition = self.upperPos ur = self.style().subControlRect(QStyle.CC_Slider, opt, QStyle.SC_SliderHandle, self) urv = self.pick(ur.center()) # span minv = min(lrv, urv) maxv = max(lrv, urv) c = self.style().subControlRect(QStyle.CC_Slider, opt, QStyle.SC_SliderGroove, self).center() spanRect = QRect(QPoint(c.x() - 2, minv), QPoint(c.x() + 1, maxv)) if self.orientation() == QtCore.Qt.Horizontal: spanRect = QRect(QPoint(minv, c.y() - 2), QPoint(maxv, c.y() + 1)) self.drawSpan(painter, spanRect) # handles if self.lastPressed == QxtSpanSlider.LowerHandle: self.drawHandle(painter, QxtSpanSlider.UpperHandle) self.drawHandle(painter, QxtSpanSlider.LowerHandle) else: self.drawHandle(painter, QxtSpanSlider.LowerHandle) self.drawHandle(painter, QxtSpanSlider.UpperHandle)
def paintEvent(self, event): """ Override the paint event to draw both slider handles. """ # based on the paintEvent for QSlider: # http://qt.gitorious.org/qt/qt/blobs/master/src/gui/widgets/qslider.cpp painter = QPainter(self) style = self.style() low, high = self._low, self._high # Draw the low handle along with the groove and ticks. opt = QStyleOptionSlider() self.initStyleOption(opt) opt.subControls = QStyle.SC_SliderGroove | QStyle.SC_SliderHandle if self.tickPosition() != self.NoTicks: opt.subControls |= QStyle.SC_SliderTickmarks if (self._pressed_control and self._active_thumb == self.LowThumb or self._active_thumb == self.BothThumbs): opt.activeSubControls = self._pressed_control opt.state |= QStyle.State_Sunken else: opt.activeSubControls = QStyle.SC_None opt.sliderPosition = low opt.sliderValue = low style.drawComplexControl(QStyle.CC_Slider, opt, painter, self) # Draw high handle. The groove and ticks do not need repainting. opt = QStyleOptionSlider() self.initStyleOption(opt) opt.subControls = QStyle.SC_SliderHandle if (self._pressed_control and self._active_thumb == self.HighThumb or self._active_thumb == self.BothThumbs): opt.activeSubControls = self._pressed_control opt.state |= QStyle.State_Sunken else: opt.activeSubControls = QStyle.SC_None opt.sliderPosition = high opt.sliderValue = high style.drawComplexControl(QStyle.CC_Slider, opt, painter, self)
def paintEvent(self, event): painter = QStylePainter(self) # ticks opt = QStyleOptionSlider() self.initStyleOption(opt) opt.subControls = QStyle.SC_SliderTickmarks painter.drawComplexControl(QStyle.CC_Slider, opt) # groove opt.sliderPosition = 20 opt.sliderValue = 0 opt.subControls = QStyle.SC_SliderGroove painter.drawComplexControl(QStyle.CC_Slider, opt) # handle rects opt.sliderPosition = self.lowerPos lr = self.style().subControlRect(QStyle.CC_Slider, opt, QStyle.SC_SliderHandle, self) lrv = self.pick(lr.center()) opt.sliderPosition = self.upperPos ur = self.style().subControlRect(QStyle.CC_Slider, opt, QStyle.SC_SliderHandle, self) urv = self.pick(ur.center()) # span minv = min(lrv, urv) maxv = max(lrv, urv) c = self.style().subControlRect(QStyle.CC_Slider, opt, QStyle.SC_SliderGroove, self).center() spanRect = QRect(QPoint(c.x() - 2, minv), QPoint(c.x() + 1, maxv)) if self.orientation() == QtCore.Qt.Horizontal: spanRect = QRect(QPoint(minv, c.y() - 2), QPoint(maxv, c.y() + 1)) self.drawSpan(painter, spanRect) # handles if self.lastPressed == QxtSpanSlider.LowerHandle: self.drawHandle(painter, QxtSpanSlider.UpperHandle) self.drawHandle(painter, QxtSpanSlider.LowerHandle) else: self.drawHandle(painter, QxtSpanSlider.LowerHandle) self.drawHandle(painter, QxtSpanSlider.UpperHandle)