Metadata-Version: 2.1
Name: QtRangeSlider
Version: 0.1.0rc2
Summary: Multi-handle range slider widget for PyQt/PySide
Home-page: https://github.com/tlambert03/QtRangeSlider
Author: Talley Lambert
Author-email: talley.lambert@gmail.com
License: BSD-3
Project-URL: Source, https://github.com/tlambert03/QtRangeSlider
Project-URL: Tracker, https://github.com/tlambert03/QtRangeSlider/issues
Project-URL: Changelog, https://github.com/tlambert03/QtRangeSlider/blob/master/CHANGELOG.md
Keywords: qt,range slider,widget
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: X11 Applications :: Qt
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Topic :: Desktop Environment
Classifier: Topic :: Software Development
Classifier: Topic :: Software Development :: User Interfaces
Classifier: Topic :: Software Development :: Widget Sets
Requires-Python: >=3.6
Description-Content-Type: text/markdown
Provides-Extra: dev
Requires-Dist: ipython ; extra == 'dev'
Requires-Dist: jedi (<0.18.0) ; extra == 'dev'
Requires-Dist: isort ; extra == 'dev'
Requires-Dist: mypy ; extra == 'dev'
Requires-Dist: pre-commit ; extra == 'dev'
Requires-Dist: tox ; extra == 'dev'
Requires-Dist: tox-conda ; extra == 'dev'
Requires-Dist: pytest ; extra == 'dev'
Requires-Dist: pytest-qt ; extra == 'dev'
Requires-Dist: pytest-cov ; extra == 'dev'
Requires-Dist: pyqt5 ; extra == 'dev'
Provides-Extra: pyqt5
Requires-Dist: pyqt5 ; extra == 'pyqt5'
Provides-Extra: pyqt6
Requires-Dist: pyqt6 ; extra == 'pyqt6'
Provides-Extra: pyside2
Requires-Dist: pyside2 ; extra == 'pyside2'
Provides-Extra: pyside6
Requires-Dist: pyside6 ; extra == 'pyside6'
Provides-Extra: testing
Requires-Dist: tox ; extra == 'testing'
Requires-Dist: tox-conda ; extra == 'testing'
Requires-Dist: pytest ; extra == 'testing'
Requires-Dist: pytest-qt ; extra == 'testing'
Requires-Dist: pytest-cov ; extra == 'testing'

# QtRangeSlider

[![License](https://img.shields.io/pypi/l/QtRangeSlider.svg?color=green)](https://github.com/tlambert03/QtRangeSlider/raw/master/LICENSE)
[![PyPI](https://img.shields.io/pypi/v/QtRangeSlider.svg?color=green)](https://pypi.org/project/QtRangeSlider)
[![Python
Version](https://img.shields.io/pypi/pyversions/QtRangeSlider.svg?color=green)](https://python.org)
[![Test](https://github.com/tlambert03/QtRangeSlider/actions/workflows/test_and_deploy.yml/badge.svg)](https://github.com/tlambert03/QtRangeSlider/actions/workflows/test_and_deploy.yml)
[![codecov](https://codecov.io/gh/tlambert03/QtRangeSlider/branch/master/graph/badge.svg)](https://codecov.io/gh/tlambert03/QtRangeSlider)

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

![slider](images/slider.png)

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`](https://doc.qt.io/qt-5/qslider.html)... but with multiple handles!

- `QRangeSlider` inherits from [`QSlider`](https://doc.qt.io/qt-5/qslider.html)
  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:

```sh
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:

```python
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](https://doc.qt.io/qt-5/qslider.html).  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:

```python
range_slider.value() -> Tuple[int, ...]
```

```python
range_slider.setValue(val: Sequence[int]) -> None
```

##### Notifier Signal:

```python
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](https://doc.qt.io/qt-5/qabstractslider.html#tracking-prop) is enabled (the default), this is identical to [`value`](#value--tupleint-).

##### Access Functions:

```python
range_slider.sliderPosition() -> Tuple[int, ...]
```

```python
range_slider.setSliderPosition(val: Sequence[int]) -> None
```

##### Notifier Signal:

```python
sliderMoved(Tuple[int, ...])
```

------

## Example

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](https://doc.qt.io/qt-5/stylesheet-reference.html), 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 code for these example widgets is [here](examples/demo_widget.py)

<details>

<summary><em>See style sheet used for this example</em></summary>

```css
/* Because QRangeSlider inherits QSlider, it will also inherit styles */
QSlider::groove:horizontal {
   border: 0px;
   background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #FDE282, stop:1 #EB9A5D);
   height: 16px;
   border-radius: 2px;
}

QSlider::handle:horizontal {
    background: #271848;
    border: 1px solid #583856;
    width: 18px;
    margin: -2px 0;
    border-radius: 3px;
}

QSlider::handle:hover {
   background-color: #2F4F4F;
}

/* "QSlider::sub-page" will style the "bar" area between the QRangeSlider handles */
QSlider::sub-page:horizontal {
    background: #AF5A50;
    border-radius: 2px;
}
```

</details>

### macOS

##### Catalina
![mac](images/demo_darwin.png)

##### Big Sur
![mac](images/demo_darwin11.png)

### Windows

![mac](images/demo_windows.png)

### Linux

![mac](images/demo_linux.png)

## Issues

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

[file an issue]: https://github.com/tlambert03/QtRangeSlider/issues


