Multi-handle range slider widget for PyQt/PySide

Overview

QtRangeSlider

License PyPI Python Version Test codecov

The missing multi-handle range slider widget for PyQt & PySide

slider

The goal of this package is to provide a Range Slider (a slider with 2 or more handles) that feels as "native" as possible. Styles should match the OS by default, and the slider should behave like a standard QSlider... but with multiple handles!

  • QRangeSlider inherits from QSlider and attempts to match the Qt API as closely as possible
  • Uses platform-specific styles (for handle, groove, & ticks) but also supports QSS style sheets.
  • Supports mouse wheel and keypress (soon) events
  • Supports PyQt5, PyQt6, PySide2 and PySide6
  • Supports more than 2 handles (e.g. slider.setValue([0, 10, 60, 80]))

Installation

You can install QtRangeSlider via pip:

pip install qtrangeslider

# NOTE: you must also install a Qt Backend.
# PyQt5, PySide2, PyQt6, and PySide6 are supported
# As a convenience you can install them as extras:
pip install qtrangeslider[pyqt5]

API

To create a slider:

from qtrangeslider import QRangeSlider

# as usual:
# you must create a QApplication before create a widget.
range_slider = QRangeSlider()

As QRangeSlider inherits from QtWidgets.QSlider, you can use all of the same methods available in the QSlider API. The major difference is that value and sliderPosition are reimplemented as tuples of int (where the length of the tuple is equal to the number of handles in the slider.)

value: Tuple[int, ...]

This property holds the current value of all handles in the slider.

The slider forces all values to be within the legal range: minimum <= value <= maximum.

Changing the value also changes the sliderPosition.

Access Functions:
range_slider.value() -> Tuple[int, ...]
range_slider.setValue(val: Sequence[int]) -> None
Notifier Signal:
valueChanged(Tuple[int, ...])

sliderPosition: Tuple[int, ...]

This property holds the current slider positions. It is a tuple with length equal to the number of handles.

If tracking is enabled (the default), this is identical to value.

Access Functions:
range_slider.sliderPosition() -> Tuple[int, ...]
range_slider.setSliderPosition(val: Sequence[int]) -> None
Notifier Signal:
sliderMoved(Tuple[int, ...])

Additional properties

These options are in addition to the Qt QSlider API, and control the behavior of the bar between handles.

getter setter type default description
barIsVisible setBarIsVisible
hideBar / showBar
bool True Whether the bar between handles is visible.
barMovesAllHandles setBarMovesAllHandles bool True Whether clicking on the bar moves all handles or just the nearest
barIsRigid setBarIsRigid bool True Whether bar length is constant or "elastic" when dragging the bar beyond min/max.

Examples

These screenshots show QRangeSlider (multiple handles) next to the native QSlider (single handle). With no styles applied, QRangeSlider will match the native OS style of QSlider – with or without tick marks. When styles have been applied using Qt Style Sheets, then QRangeSlider will inherit any styles applied to QSlider (since it inherits from QSlider). If you'd like to style QRangeSlider differently than QSlider, then you can also target it directly in your style sheet. The one "special" property for QRangeSlider is qproperty-barColor, which sets the color of the bar between the handles.

The code for these example widgets is here

See style sheet used for this example
/*
Because QRangeSlider inherits from QSlider, it will also inherit styles
*/
QSlider {
    min-height: 20px;
}

QSlider::groove:horizontal {
    border: 0px;
    background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
                                stop:0 #777, stop:1 #aaa);
    height: 20px;
    border-radius: 10px;
}

QSlider::handle {
    background: qradialgradient(cx:0, cy:0, radius: 1.2, fx:0.5,
                                fy:0.5, stop:0 #eef, stop:1 #000);
    height: 20px;
    width: 20px;
    border-radius: 10px;
}

/*
"QSlider::sub-page" is the one exception ...
(it styles the area to the left of the QSlider handle)
*/
QSlider::sub-page:horizontal {
    background: #447;
    border-top-left-radius: 10px;
    border-bottom-left-radius: 10px;
}

/*
for QRangeSlider: use "qproperty-barColor".  "sub-page" will not work.
*/
QRangeSlider {
    qproperty-barColor: #447;
}

macOS

Catalina

mac10

Big Sur

mac11

Windows

window

Linux

linux

Labeled Sliders

This package also includes two "labeled" slider variants. One for QRangeSlider, and one for the native QSlider:

QLabeledRangeSlider

labeled_range

from qtrangeslider import QLabeledRangeSlider

This has the same API as QRangeSlider with the following additional options:

handleLabelPosition/setHandleLabelPosition

Where/whether labels are shown adjacent to slider handles.

type: QLabeledRangeSlider.LabelPosition

default: LabelPosition.LabelsAbove

options:

  • LabelPosition.NoLabel (no labels shown adjacent to handles)
  • LabelPosition.LabelsAbove
  • LabelPosition.LabelsBelow
  • LabelPosition.LabelsRight (alias for LabelPosition.LabelsAbove)
  • LabelPosition.LabelsLeft (alias for LabelPosition.LabelsBelow)

edgeLabelMode/setEdgeLabelMode

type: QLabeledRangeSlider.EdgeLabelMode

default: EdgeLabelMode.LabelsAbove

options:

  • EdgeLabelMode.NoLabel: no labels shown at slider extremes
  • EdgeLabelMode.LabelIsRange: edge labels shown the min/max values
  • EdgeLabelMode.LabelIsValue: edge labels shown the slider range

fine tuning position of labels:

If you find that you need to fine tune the position of the handle labels:

  • QLabeledRangeSlider.label_shift_x: adjust horizontal label position
  • QLabeledRangeSlider.label_shift_y: adjust vertical label position

QLabeledSlider

labeled_range

from qtrangeslider import QLabeledSlider

(no additional options at this point)

Issues

If you encounter any problems, please file an issue along with a detailed description.

Issues
  • Must construct a QApplication before a QWidget with PySide6

    Must construct a QApplication before a QWidget with PySide6

    Describe the bug Everytime I try to instantiate a QRangeSlider I get a QWidget: Must construct a QApplication before a QWidget

    To Reproduce

    import sys
    
    from PySide6 import QtCore, QtWidgets, QtGui
    from qtrangeslider import QRangeSlider
    from qtrangeslider.qtcompat.QtCore import Qt as compactQt
    
    app = QtWidgets.QApplication(sys.argv)
    widget = QRangeSlider(compactQt.Horizontal)
    widget.show()
    

    Expected behavior QApplication is created so this work, right ? Also QRangeSlider doesn't accept Qt.Horizontal if I use PySide6.QtGui.Qt.

    Screenshots N/A

    Desktop (please complete the following information):

    • OS with version : Manjaro
    • Qt Backend : PySide6
    • Python version : 3.9.5

    Let me know if more information is needed to slove this.

    opened by seifane 6
  • QLabeledRangeSlider does not support methods using the bar

    QLabeledRangeSlider does not support methods using the bar

    QLabeledRangeSlider does not seem to support methods using the bar, while there is a bar present. Feature request: support bar methods such as setBarIsVisible, setBarMovesAllHandles and setBarIsRigid.

    Code: a = QLabeledRangeSlider() a.hideBar() Traceback (most recent call last): File "", line 1, in a.hideBar() AttributeError: 'QLabeledRangeSlider' object has no attribute 'hideBar'

    Amazing package by the way!

    opened by OMGSuperZappie 2
  • FloatSlider

    FloatSlider

    Adds QDoubleSlider, QDoubleRangeSlider, QLabeledDoubleSlider, and QLabeledDoubleRangeSlider,

    Untitled
    opened by tlambert03 1
  • Mouse interaction tests

    Mouse interaction tests

    trying to add mouse tests

    opened by tlambert03 1
  • cov changes

    cov changes

    opened by tlambert03 1
  • Prevent handle and label overlap

    Prevent handle and label overlap

    opened by tlambert03 1
  • Fix slider signature overloads

    Fix slider signature overloads

    opened by tlambert03 1
  • add legacy qt tests

    add legacy qt tests

    add tests for older qt versions

    opened by tlambert03 1
  • new-float-again

    new-float-again

    another attempt at a float slider that works for range sliders and doesn't have overflow issues

    opened by tlambert03 1
  • Generic slider

    Generic slider

    I keep running into annoying edge cases with the "classic" float slider approach that scales the values to some integer space for Qt. I have been using a generic slider model for QtRangeSlider, but this PR takes that pattern and uses it more generally for the FloatSlider (and QtRangeSlider is now just a variant of the _GenericSlider that accepts value of a sequence of scalars... one for each handle).

    It looks like tremendous overkill (and it may be?) ... but it's the only way I've been able to achieve all of the test cases I want to

    closes #13

    opened by tlambert03 1
Releases(v0.1.3)
Owner
Talley Lambert
Microscopist at Harvard Medical School
Talley Lambert
UberGui is a lightweight multi-threaded, webRender UI module for TouchDesigner

UberGui V4 UberGui is a lightweight multi-threaded, webRender UI module for TouchDesigner projects. The aim is to solve the trifecta of challenges bui

LUCAS M MORGAN 38 Jun 19, 2021
A GUI panel to manage multi monitor on i3wm.

Monitor manager Only for I3wm (Just for now) It's about two years that I'm using i3 as my window manager and in my experience this window manager allo

Wire.Nemo 3 Nov 6, 2021
Image comparison slider component for Streamlit

Streamlit Image Comparison Component A simple Streamlit Component to compare images with a slider in Streamlit apps using Knightlab's JuxtaposeJS. It

fatih 4 Nov 25, 2021
Alt1-compatible widget host for RuneScape 3

RuneKit Alt1-compatible toolbox for RuneScape 3, for Linux and macOS. Compatibility macOS installation guide Running This project use Poetry as packag

Manatsawin Hanmongkolchai 40 Nov 16, 2021
Location field and widget for Django. It supports Google Maps, OpenStreetMap and Mapbox

django-location-field Let users pick locations using a map widget and store its latitude and longitude. Stable version: django-location-field==2.1.0 D

Caio Ariede 460 Nov 27, 2021
A better and faster multiple selection widget with suggestions

django-searchable-select A better and faster multiple selection widget with suggestions for Django This project is looking for maintainers! Please ope

Andrew Dunai 98 Nov 19, 2021
Django model field that can hold a geoposition, and corresponding widget

django-geoposition A model field that can hold a geoposition (latitude/longitude), and corresponding admin/form widget. Prerequisites Starting with ve

Philipp Bosch 322 Nov 13, 2021
Location field and widget for Django. It supports Google Maps, OpenStreetMap and Mapbox

django-location-field Let users pick locations using a map widget and store its latitude and longitude. Stable version: django-location-field==2.1.0 D

Caio Ariede 460 Nov 27, 2021
FrostedGlass is a translucent frosted glass effect widget, that creates a context with the background behind it.

FrostedGlass FrostedGlass is a translucent frosted glass effect widget, that creates a context with the background behind it. The effect is drawn on t

Kivy Garden 7 Nov 10, 2021
A GUI widget for Linux to show current time in different timezones.

A GUI widget to show current time in different timezones (under development). To use this widget: Run scripts/startup.py Select a country. A list of t

B.Jothin kumar 6 Nov 28, 2021
A Windows Dock Widget Written In Pure Python

VEПUS A Windows Dock Widget Written In Pure Python What is Venus? Venus is a Dock Widget for your desktops interface. It adds a couple of really cool

Secrets 5 Nov 21, 2021
A small bot to interact with the reddit API. Get top viewers and update the sidebar widget.

LiveStream_Reddit_Bot Get top twitch and facebook stream viewers for a game and update the sidebar widget and old reddit sidebar to show your communit

Tristan Wise 1 Nov 21, 2021
Define fortify and autoplot functions to allow ggplot2 to handle some popular R packages.

ggfortify This package offers fortify and autoplot functions to allow automatic ggplot2 to visualize statistical result of popular R packages. Check o

Sinhrks 478 Nov 27, 2021
Automatically build ARIMA, SARIMAX, VAR, FB Prophet and XGBoost Models on Time Series data sets with a Single Line of Code. Now updated with Dask to handle millions of rows.

Auto_TS: Auto_TimeSeries Automatically build multiple Time Series models using a Single Line of Code. Now updated with Dask. Auto_timeseries is a comp

AutoViz and Auto_ViML 336 Nov 30, 2021
A CBV to handle multiple forms in one view

django-shapeshifter A common problem in Django is how to have a view, especially a class-based view that can display and process multiple forms at onc

Kenneth Love 154 Nov 30, 2021
🔄 🌐 Handle thousands of HTTP requests, disk writes, and other I/O-bound tasks simultaneously with Python's quintessential async libraries.

?? ?? Handle thousands of HTTP requests, disk writes, and other I/O-bound tasks simultaneously with Python's quintessential async libraries.

Hackers and Slackers 4 Oct 13, 2021
Py_extract is a simple, light-weight python library to handle some extraction tasks using less lines of code

py_extract Py_extract is a simple, light-weight python library to handle some extraction tasks using less lines of code. Still in Development Stage! I

I'm Not A Bot #Left_TG 7 Nov 7, 2021
OpenStickFirmware is open source software designed to handle any and all tasks required in a custom Fight Stick

OpenStickFirmware is open source software designed to handle any and all tasks required in a custom Fight Stick. It can handle being the brains of your entire stick, or just handling the bells and whistles while your Brook board talks to your console.

Sleep Unit 10 Nov 11, 2021
A CBV to handle multiple forms in one view

django-shapeshifter A common problem in Django is how to have a view, especially a class-based view that can display and process multiple forms at onc

Kenneth Love 155 Nov 10, 2021
A package to handle images in django

Django Image Tools Django Image Tools is a small app that will allow you to manage your project's images without worrying much about image sizes, how

The Bonsai Studio 41 Aug 1, 2021
Endpoints is a lightweight REST api framework written in python and used in multiple production systems that handle millions of requests daily.

Endpoints Quickest API builder in the West! Endpoints is a lightweight REST api framework written in python and used in multiple production systems th

Jay Marcyes 31 Oct 23, 2021
A crude Hy handle on Pandas library

Quickstart Hyenas is a curde Hy handle written on top of Pandas API to allow for more elegant access to data-scientist's powerhouse that is Pandas. In

Peter Výboch 3 Oct 28, 2021
Console to handle object storage using JSON serialization and deserealization.

Console to handle object storage using JSON serialization and deserealization. This is a team project to develop a Python3 console that emulates the AirBnb object management.

Ronald Alexander 1 Nov 30, 2021
Repository providing a wide range of self-supervised pretrained models for computer vision tasks.

Hierarchical Pretraining: Research Repository This is a research repository for reproducing the results from the project "Self-supervised pretraining

Colorado Reed 39 Nov 20, 2021
WHENet: Real-time Fine-Grained Estimation for Wide Range Head Pose

WHENet: Real-time Fine-Grained Estimation for Wide Range Head Pose Yijun Zhou and James Gregson - BMVC2020 Abstract: We present an end-to-end head-pos

null 272 Nov 22, 2021
Range Image-based LiDAR Localization for Autonomous Vehicles Using Mesh Maps

Range Image-based 3D LiDAR Localization This repo contains the code for our ICRA2021 paper: Range Image-based LiDAR Localization for Autonomous Vehicl

Photogrammetry & Robotics Bonn 109 Nov 24, 2021
We envision models that are pre-trained on a vast range of domain-relevant tasks to become key for molecule property prediction

We envision models that are pre-trained on a vast range of domain-relevant tasks to become key for molecule property prediction. This repository aims to give easy access to state-of-the-art pre-trained models.

GMUM 54 Nov 7, 2021
The PyTorch improved version of TPAMI 2017 paper: Face Alignment in Full Pose Range: A 3D Total Solution.

Face Alignment in Full Pose Range: A 3D Total Solution By Jianzhu Guo. [Updates] 2020.8.30: The pre-trained model and code of ECCV-20 are made public

Jianzhu Guo 3.1k Dec 2, 2021