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 mouseMoveEvent(self, event): if self.__pressed_control not in (QStyle.SC_SliderGroove, QStyle.SC_SliderHandle): event.ignore() return event.accept() opt = QStyleOptionSlider() self.initStyleOption(opt) pos = self._pixelPosToRangeValue(self._pick(event.pos())) if self.__active_slider < 0: offset = pos - self.__click_offset self.__max_position = min(self.__max_position + offset, self.maximum()) self.__min_position = max(self.__min_position + offset, self.minimum()) self.__click_offset = pos else: if self.__active_slider == 0: self.__min_position = max(self.minimum(), pos) self.__max_position = min( self.maximum(), max(self.__max_position, self.__min_position + 1)) else: self.__max_position = min(self.maximum(), pos) self.__min_position = max( self.minimum(), min(self.__min_position, self.__max_position - 1)) self.update() self.slidersMoved.emit(self.__min_position, self.__max_position) # This is different from QAbstractSlider, which sets the value # insider triggerAction() which would be called here instead. # But I don't want to override that as well, so simply: if self.hasTracking(): self.setValues(self.__min_position, self.__max_position)
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 mouseMoveEvent(self, event): if self.__pressed_control not in (QStyle.SC_SliderGroove, QStyle.SC_SliderHandle): event.ignore() return event.accept() opt = QStyleOptionSlider() self.initStyleOption(opt) pos = self._pixelPosToRangeValue(self._pick(event.pos())) if self.__new_selection_drawing_origin: # Drawing new time window if pos <= self.__click_offset and self.__active_slider != 0: self.__active_slider = 0 self._max_position = self.__new_selection_drawing_origin[1] elif pos > self.__click_offset and self.__active_slider != 1: self.__active_slider = 1 self._min_position = self.__new_selection_drawing_origin[0] if self.__active_slider < 0: # Moving the time window width = self._max_position - self._min_position offset = pos - self.__click_offset if offset >= 0: self._max_position = min(self.maximum(), self._max_position + offset) self._min_position = max(self.minimum(), min(self._min_position + offset, self._max_position - width)) else: self._min_position = max(self.minimum(), self._min_position + offset) self._max_position = min(self.maximum(), max(self._max_position + offset, self._min_position + width)) self.__click_offset = pos else: # Moving a handle if self.__active_slider == 0: if not self.__new_selection_drawing_origin \ and self._max_position <= pos < self.maximum(): # Flip to other slider self.__active_slider = 1 self._min_position = self._max_position self._max_position = min(self.maximum(), max(pos, self._min_position + 1)) else: self._min_position = max(self.minimum(), min(pos, self._max_position - 1)) else: if not self.__new_selection_drawing_origin \ and self.minimum() < pos <= self._min_position: # Flip to other slider self.__active_slider = 0 self._max_position = self._min_position self._min_position = max(self.minimum(), min(pos, self._max_position - 1)) else: self._max_position = min(self.maximum(), max(pos, self._min_position + 1)) self.update() self.slidersMoved.emit(self._min_position, self._max_position) # This is different from QAbstractSlider, which sets the value # insider triggerAction() which would be called here instead. # But I don't want to override that as well, so simply: if self.hasTracking(): self.__tracked_selection = (self._min_position, self._max_position)
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 paintEvent(self, e): #print("hover: ",self._hover,",press: ",self._press) painter = QStylePainter(self) # prepare the drawing options # for drawing slider groove opt = QStyleOptionSlider() opt.initFrom(self) opt.subControls = QStyle.SC_SliderGroove opt.maximum = self.__steps opt.minimum = 0 opt.orientation = self.orientation() opt.sliderPosition = self.__position0 opt.sliderValue = self.__value0 if self._tickList is not None: opt.tickPosition = QSlider.TicksBelow else: opt.tickPosition = QSlider.NoTicks handleWidth = self._handleWidth measureWidth = self.width() - handleWidth - handleWidth painter.drawComplexControl(QStyle.CC_Slider, opt) # draw tickmarks if self._tickList is not None: painter.drawPixmap(self._handleWidth, self.height() - self._tickHeight, self._tickImage) # handle colors colorPRESS = QColor(204, 204, 204) colorHOVER = QColor(23, 23, 23) colorNORMAL = QColor(0, 122, 217) if self.isEnabled() else colorPRESS handleHeight = self.height( ) if self._tickList is None else self.height() - self._tickHeight # draw handle 0 if self._press in {0, 2}: color = colorPRESS elif self._hover == 0: color = colorHOVER else: color = colorNORMAL self._rects[0] = r0 = QRect( self.__position0 / self.__steps * measureWidth, 0, handleWidth, handleHeight) painter.fillRect(self._rects[0], color) # draw handle 1 if self._press in {1, 2}: color = colorPRESS elif self._hover == 1: color = colorHOVER else: color = colorNORMAL self._rects[1] = r1 = QRect( self.__position1 / self.__steps * measureWidth + handleWidth, 0, handleWidth, handleHeight) painter.fillRect(self._rects[1], color) # draw inner handle if self._press == 2 or not self.isEnabled(): color = QColor(0, 0, 0, 15) elif self._hover == 2: color = QColor(0, 61, 108, 63) else: color = QColor(0, 122, 217, 63) self._rects[2] = QRect(r0.left(), r0.top(), r1.right() - r0.left() + 1, handleHeight) painter.fillRect(self._rects[2], color)