diff --git a/.gitignore b/.gitignore index df5dde7..69e5c1b 100644 --- a/.gitignore +++ b/.gitignore @@ -77,4 +77,3 @@ target/ # written by setuptools_scm */_version.py -screenshots/ diff --git a/LICENSE b/LICENSE index 48c8a64..28b89bb 100644 --- a/LICENSE +++ b/LICENSE @@ -12,7 +12,7 @@ modification, are permitted provided that the following conditions are met: this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -* Neither the name of pyqrangeslider nor the names of its +* Neither the name of QtRangeSlider nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/README.md b/README.md index eaa7dff..54b737a 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,116 @@ -# PyQRangeSlider +# QtRangeSlider -[![License](https://img.shields.io/pypi/l/PyQRangeSlider.svg?color=green)](https://github.com/tlambert03/PyQRangeSlider/raw/master/LICENSE) -[![PyPI](https://img.shields.io/pypi/v/PyQRangeSlider.svg?color=green)](https://pypi.org/project/PyQRangeSlider) -[![Python Version](https://img.shields.io/pypi/pyversions/PyQRangeSlider.svg?color=green)](https://python.org) -[![Test](https://github.com/tlambert03/PyQRangeSlider/actions/workflows/test_and_deploy.yml/badge.svg)](https://github.com/tlambert03/PyQRangeSlider/actions/workflows/test_and_deploy.yml) -[![codecov](https://codecov.io/gh/tlambert03/PyQRangeSlider/branch/master/graph/badge.svg)](https://codecov.io/gh/tlambert03/PyQRangeSlider) +[![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) -Multi-handle range slider widget for PyQt/PySide +**Multi-handle range slider widget for PyQt/PySide** -The goal of this package is to provide a QRangeSlider that feels as "native" -as possible. Styles should match the OS by default, and the slider should -behave like a standard QSlider... just with multiple handles. +![slider](screenshots/slider.png) -- Supports more than 2 handles (e.g. `slider.setValue([0, 10, 60, 80])`) -- Attempts to match QSlider API as closely as possible -- Uses platform-specific styles (for handle, groove, & ticks) but also supports QSS style sheets. +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 `PyQRangeSlider` via pip: +You can install `QtRangeSlider` via pip: - pip install pyqrangeslider +```sh +pip install qtrangeslider +# note: you must also install a Qt Backend +# supports PyQt5, PySide2, PyQt6, and PySide6 +# as a convenience you can install via extras: +pip install qtrangeslider[pyqt5] + +``` + +And then to use it: + +```python +from qtrangeslider import QRangeSlider +``` + +## API + +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) + + +## 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). + +
+ +See style sheet used for this example + +```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; +} +``` + +
+ +### macOS + +![mac](screenshots/demo_macos.png) + +### Window + +(coming) + + +### Linux + +(coming) + ## Issues -If you encounter any problems, please [file an issue] along with a detailed description. +If you encounter any problems, please [file an issue] along with a detailed +description. -[file an issue]: https://github.com/tlambert03/PyQRangeSlider/issues +[file an issue]: https://github.com/tlambert03/QtRangeSlider/issues diff --git a/examples/basic.py b/examples/basic.py index 5a0da72..d5d9841 100644 --- a/examples/basic.py +++ b/examples/basic.py @@ -1,5 +1,5 @@ -from pyqrangeslider import QRangeSlider -from pyqrangeslider.qtcompat.QtWidgets import QApplication +from qtrangeslider import QRangeSlider +from qtrangeslider.qtcompat.QtWidgets import QApplication app = QApplication([]) diff --git a/examples/multihandle.py b/examples/multihandle.py index 1d85f1e..e18557c 100644 --- a/examples/multihandle.py +++ b/examples/multihandle.py @@ -1,5 +1,5 @@ -from pyqrangeslider import QRangeSlider -from pyqrangeslider.qtcompat.QtWidgets import QApplication +from qtrangeslider import QRangeSlider +from qtrangeslider.qtcompat.QtWidgets import QApplication app = QApplication([]) diff --git a/examples/screenshots.py b/examples/screenshots.py index 2106c71..5b38a55 100644 --- a/examples/screenshots.py +++ b/examples/screenshots.py @@ -1,6 +1,6 @@ -from pyqrangeslider import QRangeSlider -from pyqrangeslider.qtcompat import QtCore -from pyqrangeslider.qtcompat import QtWidgets as QtW +from qtrangeslider import QRangeSlider +from qtrangeslider.qtcompat import QtCore +from qtrangeslider.qtcompat import QtWidgets as QtW QSS = """ @@ -65,7 +65,7 @@ class DemoWidget(QtW.QWidget): szp = QtW.QSizePolicy.Maximum left = QtW.QWidget() left.setLayout(QtW.QVBoxLayout()) - left.setContentsMargins(0, 0, 0, 0) + left.setContentsMargins(2, 2, 2, 2) label1 = QtW.QLabel("Regular QSlider Unstyled") label2 = QtW.QLabel("QRangeSliders Unstyled") label3 = QtW.QLabel("Styled Sliders (using same stylesheet)") diff --git a/pyqrangeslider/__init__.py b/qtrangeslider/__init__.py similarity index 100% rename from pyqrangeslider/__init__.py rename to qtrangeslider/__init__.py diff --git a/pyqrangeslider/_qrangeslider.py b/qtrangeslider/_qrangeslider.py similarity index 100% rename from pyqrangeslider/_qrangeslider.py rename to qtrangeslider/_qrangeslider.py diff --git a/pyqrangeslider/_tests/test_slider.py b/qtrangeslider/_tests/test_slider.py similarity index 69% rename from pyqrangeslider/_tests/test_slider.py rename to qtrangeslider/_tests/test_slider.py index 588a035..b56e0e1 100644 --- a/pyqrangeslider/_tests/test_slider.py +++ b/qtrangeslider/_tests/test_slider.py @@ -1,7 +1,7 @@ import pytest -from pyqrangeslider import QRangeSlider -from pyqrangeslider.qtcompat.QtCore import Qt +from qtrangeslider import QRangeSlider +from qtrangeslider.qtcompat.QtCore import Qt @pytest.mark.parametrize("orientation", ["Horizontal", "Vertical"]) diff --git a/pyqrangeslider/qtcompat/QtCore.py b/qtrangeslider/qtcompat/QtCore.py similarity index 100% rename from pyqrangeslider/qtcompat/QtCore.py rename to qtrangeslider/qtcompat/QtCore.py diff --git a/pyqrangeslider/qtcompat/QtGui.py b/qtrangeslider/qtcompat/QtGui.py similarity index 100% rename from pyqrangeslider/qtcompat/QtGui.py rename to qtrangeslider/qtcompat/QtGui.py diff --git a/pyqrangeslider/qtcompat/QtWidgets.py b/qtrangeslider/qtcompat/QtWidgets.py similarity index 100% rename from pyqrangeslider/qtcompat/QtWidgets.py rename to qtrangeslider/qtcompat/QtWidgets.py diff --git a/pyqrangeslider/qtcompat/__init__.py b/qtrangeslider/qtcompat/__init__.py similarity index 100% rename from pyqrangeslider/qtcompat/__init__.py rename to qtrangeslider/qtcompat/__init__.py diff --git a/screenshots/demo_macos.png b/screenshots/demo_macos.png new file mode 100644 index 0000000..612758a Binary files /dev/null and b/screenshots/demo_macos.png differ diff --git a/screenshots/slider.png b/screenshots/slider.png new file mode 100644 index 0000000..637e206 Binary files /dev/null and b/screenshots/slider.png differ diff --git a/setup.cfg b/setup.cfg index 6f20733..e85b3aa 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] -name = PyQRangeSlider -url = https://github.com/tlambert03/PyQRangeSlider +name = QtRangeSlider +url = https://github.com/tlambert03/QtRangeSlider license = BSD-3 license_file = LICENSE description = Multi-handle range slider widget for PyQt/PySide @@ -10,9 +10,9 @@ author = Talley Lambert author_email = talley.lambert@gmail.com keywords = qt, range slider, widget project_urls = - Source = https://github.com/tlambert03/PyQRangeSlider - Tracker = https://github.com/tlambert03/PyQRangeSlider/issues - Changelog = https://github.com/tlambert03/PyQRangeSlider/blob/master/CHANGELOG.md + Source = https://github.com/tlambert03/QtRangeSlider + Tracker = https://github.com/tlambert03/QtRangeSlider/issues + Changelog = https://github.com/tlambert03/QtRangeSlider/blob/master/CHANGELOG.md classifiers = Development Status :: 4 - Beta Environment :: X11 Applications :: Qt diff --git a/setup.py b/setup.py index 5cc65a5..336090f 100644 --- a/setup.py +++ b/setup.py @@ -5,6 +5,6 @@ so this file is currently here to support "pip install -e ." from setuptools import setup setup( - use_scm_version={"write_to": "pyqrangeslider/_version.py"}, + use_scm_version={"write_to": "qtrangeslider/_version.py"}, setup_requires=["setuptools_scm"], ) diff --git a/tox.ini b/tox.ini index 79bcdca..3037fb1 100644 --- a/tox.ini +++ b/tox.ini @@ -39,4 +39,4 @@ extras = pyside2: pyside2 pyqt6: pyqt6 pyside6: pyside6 -commands = pytest -v --color=yes --cov=pyqrangeslider --cov-report=xml +commands = pytest -v --color=yes --cov=qtrangeslider --cov-report=xml