Move to to qwidgets
commit 466fc7c19ace1343d23739e4058758cd21328511 Author: Talley Lambert <talley.lambert@gmail.com> Date: Wed Jun 2 20:22:38 2021 -0400 add deploy cond commit e9965e71490689935b61099225acc7f3bf5c2d48 Author: Talley Lambert <talley.lambert@gmail.com> Date: Wed Jun 2 20:20:45 2021 -0400 more precommit commit b39150b16d7d64a5530ec9a0e29e673e2b6ed0a4 Author: Talley Lambert <talley.lambert@gmail.com> Date: Wed Jun 2 19:52:42 2021 -0400 updating precommit commit d5018b38e7bc59f81cc161cca06fae829e493e3c Author: Talley Lambert <talley.lambert@gmail.com> Date: Wed Jun 2 19:42:32 2021 -0400 big reorg
11
.coveragerc
@@ -1,11 +0,0 @@
|
||||
[report]
|
||||
exclude_lines =
|
||||
pragma: no cover
|
||||
if TYPE_CHECKING:
|
||||
\.\.\.
|
||||
except ImportError*
|
||||
raise NotImplementedError()
|
||||
omit =
|
||||
qtrangeslider/_version.py
|
||||
qtrangeslider/qtcompat/*
|
||||
*_tests*
|
7
.github/workflows/test_and_deploy.yml
vendored
@@ -89,6 +89,7 @@ jobs:
|
||||
sudo apt-get install -y libdbus-1-3 libxkbcommon-x11-0 libxcb-icccm4 \
|
||||
libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 \
|
||||
libxcb-xinerama0 libxcb-xfixes0
|
||||
|
||||
- name: Linux opengl
|
||||
if: runner.os == 'Linux' && ( matrix.backend == 'pyside6' || matrix.backend == 'pyqt6' )
|
||||
run: sudo apt-get install -y libopengl0 libegl1-mesa libxcb-xinput0
|
||||
@@ -111,13 +112,13 @@ jobs:
|
||||
if: matrix.screenshot
|
||||
run: pip install . ${{ matrix.backend }}
|
||||
|
||||
- name: Screenshots
|
||||
- name: Screenshots (Linux)
|
||||
if: runner.os == 'Linux' && matrix.screenshot
|
||||
uses: GabrielBB/xvfb-action@v1
|
||||
with:
|
||||
run: python examples/demo_widget.py -snap
|
||||
|
||||
- name: Screenshots
|
||||
- name: Screenshots (macOS/Win)
|
||||
if: runner.os != 'Linux' && matrix.screenshot
|
||||
run: python examples/demo_widget.py -snap
|
||||
|
||||
@@ -133,8 +134,8 @@ jobs:
|
||||
# and requires that you have put your twine API key in your
|
||||
# github secrets (see readme for details)
|
||||
needs: [test]
|
||||
if: ${{ github.repository == 'napari/qwidgets' && contains(github.ref, 'tags') }}
|
||||
runs-on: ubuntu-latest
|
||||
if: contains(github.ref, 'tags')
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python
|
||||
|
@@ -4,20 +4,32 @@ repos:
|
||||
hooks:
|
||||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
- repo: https://github.com/asottile/setup-cfg-fmt
|
||||
rev: v1.17.0
|
||||
hooks:
|
||||
- id: setup-cfg-fmt
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: 3.9.2
|
||||
hooks:
|
||||
- id: flake8
|
||||
additional_dependencies:
|
||||
[flake8-typing-imports==1.7.0]
|
||||
exclude: examples
|
||||
- repo: https://github.com/myint/autoflake
|
||||
rev: v1.4
|
||||
hooks:
|
||||
- id: autoflake
|
||||
args: ["--in-place", "--remove-all-unused-imports"]
|
||||
- repo: https://github.com/PyCQA/isort
|
||||
rev: 5.8.0
|
||||
hooks:
|
||||
- id: isort
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v2.19.0
|
||||
rev: v2.19.1
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: [--py37-plus]
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 21.5b2
|
||||
hooks:
|
||||
- id: black
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: 3.9.2
|
||||
hooks:
|
||||
- id: flake8
|
||||
pass_filenames: true
|
||||
|
54
CONTRIBUTING.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# Contributing to this repository
|
||||
|
||||
This repository seeks to accumulate Qt-based widgets for python (PyQt & PySide)
|
||||
that are not provided in the native QtWidgets module.
|
||||
|
||||
## Clone
|
||||
|
||||
To get started fork this repository, and clone your fork:
|
||||
|
||||
```bash
|
||||
# clone your fork
|
||||
git clone https://github.com/<your_organization>/qwidgets
|
||||
cd qwidgets
|
||||
|
||||
# install pre-commit hooks
|
||||
pre-commit install
|
||||
|
||||
# install in editable mode
|
||||
pip install -e .[dev]
|
||||
|
||||
# run tests & make sure everything is working!
|
||||
pytest
|
||||
```
|
||||
|
||||
## Targeted platforms
|
||||
|
||||
All widgets must be well-tested, and should work on:
|
||||
|
||||
- Python 3.7 and above
|
||||
- PyQt5 (5.11 and above) & PyQt6
|
||||
- PySide2 (5.11 and above) & PySide6
|
||||
- macOS, Windows, & Linux
|
||||
|
||||
Until [qtpy](https://github.com/spyder-ide/qtpy) supports PyQt6/PySide6, imports
|
||||
should use (and modify if necessary) `qwidgets.qtcompat`.
|
||||
|
||||
## Style Guide
|
||||
|
||||
All widgets should try to match the native Qt API as much as possible:
|
||||
|
||||
- Methods should use `camelCase` naming.
|
||||
- Getters/setters use the `attribute()/setAttribute()` pattern.
|
||||
- Private methods should use `_camelCaseNaming`.
|
||||
- `__init__` methods should be like Qt constructors, meaning they often don't
|
||||
include parameters for most of the widgets properties.
|
||||
- When possible, widgets should inherit from the most similar native widget
|
||||
available. It should strictly match the Qt API where it exists, and attempt to
|
||||
cover as much of the native API as possible; this includes properties, public
|
||||
functions, signals, and public slots.
|
||||
|
||||
## Testing
|
||||
|
||||
Tests can be run in the current environment with `pytest`. Or, to run tests
|
||||
against all supported python & Qt versions, run `tox`.
|
2
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 QtRangeSlider nor the names of its
|
||||
* Neither the name of qwidgets nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
|
271
README.md
@@ -1,262 +1,27 @@
|
||||
# QtRangeSlider
|
||||
# qwidgets
|
||||
|
||||
[](https://github.com/tlambert03/QtRangeSlider/raw/master/LICENSE)
|
||||
[](https://pypi.org/project/QtRangeSlider)
|
||||
**Missing widgets for PyQt/PySide**
|
||||
|
||||
[](https://github.com/napari/qwidgets/raw/master/LICENSE)
|
||||
[](https://pypi.org/project/qwidgets)
|
||||
[](https://python.org)
|
||||
[](https://github.com/tlambert03/QtRangeSlider/actions/workflows/test_and_deploy.yml)
|
||||
[](https://codecov.io/gh/tlambert03/QtRangeSlider)
|
||||
Version](https://img.shields.io/pypi/pyversions/qwidgets.svg?color=green)](https://python.org)
|
||||
[](https://github.com/napari/qwidgets/actions/workflows/test_and_deploy.yml)
|
||||
[](https://codecov.io/gh/napari/qwidgets)
|
||||
|
||||
**The missing multi-handle range slider widget for PyQt & PySide**
|
||||
|
||||

|
||||
## Widgets
|
||||
|
||||
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!
|
||||
Widgets include:
|
||||
|
||||
- `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])`)
|
||||
- Float Slider
|
||||
- Range Slider (multi-handle slider)
|
||||
- Labeled Sliders (sliders with linked spinboxes)
|
||||
- Unbound Integer SpinBox (backed by python `int`)
|
||||
|
||||
## Installation
|
||||
## Contributing
|
||||
|
||||
You can install `QtRangeSlider` via pip:
|
||||
This repository seeks to accumulate Qt-based widgets for python (PyQt & PySide)
|
||||
that are not provided in the native QtWidgets module. We welcome contributions!
|
||||
|
||||
```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, ...])
|
||||
```
|
||||
|
||||
### 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` <br>`hideBar` / `showBar` | `bool` | `True` | <small>Whether the bar between handles is visible.</small> |
|
||||
| `barMovesAllHandles` | `setBarMovesAllHandles` | `bool` | `True` | <small>Whether clicking on the bar moves all handles or just the nearest</small> |
|
||||
| `barIsRigid` | `setBarIsRigid` | `bool` | `True` | <small>Whether bar length is constant or "elastic" when dragging the bar beyond min/max.</small> |
|
||||
------
|
||||
|
||||
## 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](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 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](examples/demo_widget.py)
|
||||
|
||||
<details>
|
||||
|
||||
<summary><em>See style sheet used for this example</em></summary>
|
||||
|
||||
```css
|
||||
/*
|
||||
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;
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### macOS
|
||||
|
||||
##### Catalina
|
||||

|
||||
|
||||
##### Big Sur
|
||||

|
||||
|
||||
### Windows
|
||||
|
||||

|
||||
|
||||
### Linux
|
||||
|
||||

|
||||
|
||||
|
||||
## Labeled Sliders
|
||||
|
||||
This package also includes two "labeled" slider variants. One for `QRangeSlider`, and one for the native `QSlider`:
|
||||
|
||||
### `QLabeledRangeSlider`
|
||||
|
||||

|
||||
|
||||
```python
|
||||
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.LabelIsRange`
|
||||
|
||||
*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`
|
||||
|
||||
|
||||

|
||||
|
||||
```python
|
||||
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.
|
||||
|
||||
[file an issue]: https://github.com/tlambert03/QtRangeSlider/issues
|
||||
Please see the [Contributing Guide](CONTRIBUTING.md)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
ignore:
|
||||
- qtrangeslider/_version.py
|
||||
- qtrangeslider/qtcompat/*
|
||||
- qwidgets/_version.py
|
||||
- qwidgets/qtcompat/*
|
||||
- '*_tests*'
|
||||
coverage:
|
||||
status:
|
||||
|
235
docs/RangeSlider.md
Normal file
@@ -0,0 +1,235 @@
|
||||
# QRangeSlider
|
||||
|
||||
**The missing multi-handle range slider widget for PyQt & PySide**
|
||||
|
||||

|
||||
|
||||
- `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 more than 2 handles (e.g. `slider.setValue([0, 10, 60, 80])`)
|
||||
|
||||
------
|
||||
|
||||
## API
|
||||
|
||||
To create a slider:
|
||||
|
||||
```python
|
||||
from qwidgets 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, ...])
|
||||
```
|
||||
|
||||
### 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` <br>`hideBar` / `showBar` | `bool` | `True` | <small>Whether the bar between handles is visible.</small> |
|
||||
| `barMovesAllHandles` | `setBarMovesAllHandles` | `bool` | `True` | <small>Whether clicking on the bar moves all handles or just the nearest</small> |
|
||||
| `barIsRigid` | `setBarIsRigid` | `bool` | `True` | <small>Whether bar length is constant or "elastic" when dragging the bar beyond min/max.</small> |
|
||||
------
|
||||
|
||||
## 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](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 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](examples/demo_widget.py)
|
||||
|
||||
<details>
|
||||
|
||||
<summary><em>See style sheet used for this example</em></summary>
|
||||
|
||||
```css
|
||||
/*
|
||||
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;
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### macOS
|
||||
|
||||
##### Catalina
|
||||

|
||||
|
||||
##### Big Sur
|
||||

|
||||
|
||||
### Windows
|
||||
|
||||

|
||||
|
||||
### Linux
|
||||
|
||||

|
||||
|
||||
|
||||
## Labeled Sliders
|
||||
|
||||
This package also includes two "labeled" slider variants. One for `QRangeSlider`, and one for the native `QSlider`:
|
||||
|
||||
### `QLabeledRangeSlider`
|
||||
|
||||

|
||||
|
||||
```python
|
||||
from qwidgets 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.LabelIsRange`
|
||||
|
||||
*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`
|
||||
|
||||
|
||||

|
||||
|
||||
```python
|
||||
from qwidgets import QLabeledSlider
|
||||
```
|
||||
|
||||
(no additional options at this point)
|
||||
|
||||
## Issues
|
||||
|
||||
If you encounter any problems, please [file an issue] along with a detailed
|
||||
description.
|
||||
|
||||
[file an issue]: https://github.com/napari/qwidgets/issues
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 9.0 KiB |
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 9.0 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 86 KiB |
@@ -1,6 +1,6 @@
|
||||
from qtrangeslider import QRangeSlider
|
||||
from qtrangeslider.qtcompat.QtCore import Qt
|
||||
from qtrangeslider.qtcompat.QtWidgets import QApplication
|
||||
from qwidgets import QRangeSlider
|
||||
from qwidgets.qtcompat.QtCore import Qt
|
||||
from qwidgets.qtcompat.QtWidgets import QApplication
|
||||
|
||||
app = QApplication([])
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
from qtrangeslider import QDoubleSlider
|
||||
from qtrangeslider.qtcompat.QtCore import Qt
|
||||
from qtrangeslider.qtcompat.QtWidgets import QApplication
|
||||
from qwidgets import QDoubleSlider
|
||||
from qwidgets.qtcompat.QtCore import Qt
|
||||
from qwidgets.qtcompat.QtWidgets import QApplication
|
||||
|
||||
app = QApplication([])
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
from qtrangeslider import QRangeSlider
|
||||
from qtrangeslider.qtcompat import QtCore
|
||||
from qtrangeslider.qtcompat import QtWidgets as QtW
|
||||
from qwidgets import QRangeSlider
|
||||
from qwidgets.qtcompat import QtCore
|
||||
from qwidgets.qtcompat import QtWidgets as QtW
|
||||
|
||||
QSS = """
|
||||
QSlider {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
from qtrangeslider import QDoubleRangeSlider, QDoubleSlider, QRangeSlider
|
||||
from qtrangeslider.qtcompat.QtCore import Qt
|
||||
from qtrangeslider.qtcompat.QtWidgets import QApplication, QVBoxLayout, QWidget
|
||||
from qwidgets import QDoubleRangeSlider, QDoubleSlider, QRangeSlider
|
||||
from qwidgets.qtcompat.QtCore import Qt
|
||||
from qwidgets.qtcompat.QtWidgets import QApplication, QVBoxLayout, QWidget
|
||||
|
||||
app = QApplication([])
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
from qtrangeslider import QDoubleSlider
|
||||
from qtrangeslider.qtcompat.QtCore import Qt
|
||||
from qtrangeslider.qtcompat.QtWidgets import QApplication
|
||||
from qwidgets import QDoubleSlider
|
||||
from qwidgets.qtcompat.QtCore import Qt
|
||||
from qwidgets.qtcompat.QtWidgets import QApplication
|
||||
|
||||
app = QApplication([])
|
||||
|
||||
|
@@ -1,16 +1,11 @@
|
||||
from qtrangeslider._labeled import (
|
||||
from qwidgets import (
|
||||
QLabeledDoubleRangeSlider,
|
||||
QLabeledDoubleSlider,
|
||||
QLabeledRangeSlider,
|
||||
QLabeledSlider,
|
||||
)
|
||||
from qtrangeslider.qtcompat.QtCore import Qt
|
||||
from qtrangeslider.qtcompat.QtWidgets import (
|
||||
QApplication,
|
||||
QHBoxLayout,
|
||||
QVBoxLayout,
|
||||
QWidget,
|
||||
)
|
||||
from qwidgets.qtcompat.QtCore import Qt
|
||||
from qwidgets.qtcompat.QtWidgets import QApplication, QHBoxLayout, QVBoxLayout, QWidget
|
||||
|
||||
app = QApplication([])
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
from qtrangeslider import QRangeSlider
|
||||
from qtrangeslider.qtcompat.QtWidgets import QApplication
|
||||
from qwidgets import QRangeSlider
|
||||
from qwidgets.qtcompat.QtWidgets import QApplication
|
||||
|
||||
app = QApplication([])
|
||||
|
||||
|
26
qwidgets/__init__.py
Normal file
@@ -0,0 +1,26 @@
|
||||
"""qwidgets is a collection of QtWidgets for python."""
|
||||
try:
|
||||
from ._version import version as __version__
|
||||
except ImportError:
|
||||
__version__ = "unknown"
|
||||
|
||||
|
||||
from .sliders import (
|
||||
QDoubleRangeSlider,
|
||||
QDoubleSlider,
|
||||
QLabeledDoubleRangeSlider,
|
||||
QLabeledDoubleSlider,
|
||||
QLabeledRangeSlider,
|
||||
QLabeledSlider,
|
||||
QRangeSlider,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"QDoubleRangeSlider",
|
||||
"QDoubleSlider",
|
||||
"QLabeledDoubleRangeSlider",
|
||||
"QLabeledDoubleSlider",
|
||||
"QLabeledRangeSlider",
|
||||
"QLabeledSlider",
|
||||
"QRangeSlider",
|
||||
]
|
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright © 2014-2015 Colin Duquesnoy
|
||||
# Copyright © 2009- The Spyder Development Team
|
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright © 2014-2015 Colin Duquesnoy
|
||||
# Copyright © 2009- The Spyder Development Team
|
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright © 2014-2015 Colin Duquesnoy
|
||||
# Copyright © 2009- The Spyder Developmet Team
|
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright © 2009- The Spyder Development Team
|
||||
# Copyright © 2014-2015 Colin Duquesnoy
|
||||
@@ -147,7 +146,7 @@ if API in PYSIDE6_API:
|
||||
if API is None:
|
||||
raise PythonQtError(
|
||||
"No Qt bindings could be found.\nYou must install one of the following packages "
|
||||
"to use QtRangeSlider: PyQt5, PyQt6, PySide2, or PySide6"
|
||||
"to use qwidgets: PyQt5, PyQt6, PySide2, or PySide6"
|
||||
)
|
||||
|
||||
# If a correct API name is passed to QT_API and it could not be found,
|
@@ -1,8 +1,3 @@
|
||||
try:
|
||||
from ._version import version as __version__
|
||||
except ImportError:
|
||||
__version__ = "unknown"
|
||||
|
||||
from ._labeled import (
|
||||
QLabeledDoubleRangeSlider,
|
||||
QLabeledDoubleSlider,
|
@@ -1,9 +1,7 @@
|
||||
from typing import Generic, List, Sequence, Tuple, TypeVar, Union
|
||||
|
||||
from ._generic_slider import CC_SLIDER, SC_GROOVE, SC_HANDLE, SC_NONE, _GenericSlider
|
||||
from ._range_style import RangeSliderStyle, update_styles_from_stylesheet
|
||||
from .qtcompat import QtGui
|
||||
from .qtcompat.QtCore import (
|
||||
from ..qtcompat import QtGui
|
||||
from ..qtcompat.QtCore import (
|
||||
Property,
|
||||
QEvent,
|
||||
QPoint,
|
||||
@@ -13,7 +11,9 @@ from .qtcompat.QtCore import (
|
||||
Qt,
|
||||
Signal,
|
||||
)
|
||||
from .qtcompat.QtWidgets import QSlider, QStyle, QStyleOptionSlider, QStylePainter
|
||||
from ..qtcompat.QtWidgets import QSlider, QStyle, QStyleOptionSlider, QStylePainter
|
||||
from ._generic_slider import CC_SLIDER, SC_GROOVE, SC_HANDLE, SC_NONE, _GenericSlider
|
||||
from ._range_style import RangeSliderStyle, update_styles_from_stylesheet
|
||||
|
||||
_T = TypeVar("_T")
|
||||
|
@@ -22,9 +22,9 @@ QRangeSlider.
|
||||
|
||||
from typing import Generic, TypeVar
|
||||
|
||||
from .qtcompat import QtGui
|
||||
from .qtcompat.QtCore import QEvent, QPoint, QPointF, QRect, Qt, Signal
|
||||
from .qtcompat.QtWidgets import (
|
||||
from ..qtcompat import QtGui
|
||||
from ..qtcompat.QtCore import QEvent, QPoint, QPointF, QRect, Qt, Signal
|
||||
from ..qtcompat.QtWidgets import (
|
||||
QApplication,
|
||||
QSlider,
|
||||
QStyle,
|
@@ -1,10 +1,9 @@
|
||||
from enum import IntEnum
|
||||
from functools import partial
|
||||
|
||||
from ._sliders import QDoubleRangeSlider, QDoubleSlider, QRangeSlider
|
||||
from .qtcompat.QtCore import QPoint, QSize, Qt, Signal
|
||||
from .qtcompat.QtGui import QFontMetrics, QValidator
|
||||
from .qtcompat.QtWidgets import (
|
||||
from ..qtcompat.QtCore import QPoint, QSize, Qt, Signal
|
||||
from ..qtcompat.QtGui import QFontMetrics, QValidator
|
||||
from ..qtcompat.QtWidgets import (
|
||||
QAbstractSlider,
|
||||
QApplication,
|
||||
QDoubleSpinBox,
|
||||
@@ -16,6 +15,7 @@ from .qtcompat.QtWidgets import (
|
||||
QVBoxLayout,
|
||||
QWidget,
|
||||
)
|
||||
from ._sliders import QDoubleRangeSlider, QDoubleSlider, QRangeSlider
|
||||
|
||||
|
||||
class LabelPosition(IntEnum):
|
||||
@@ -32,7 +32,7 @@ class EdgeLabelMode(IntEnum):
|
||||
LabelIsValue = 2
|
||||
|
||||
|
||||
class SliderProxy:
|
||||
class _SliderProxy:
|
||||
_slider: QSlider
|
||||
|
||||
def value(self):
|
||||
@@ -112,7 +112,7 @@ def _handle_overloaded_slider_sig(args, kwargs):
|
||||
return parent, orientation
|
||||
|
||||
|
||||
class QLabeledSlider(SliderProxy, QAbstractSlider):
|
||||
class QLabeledSlider(_SliderProxy, QAbstractSlider):
|
||||
_slider_class = QSlider
|
||||
_slider: QSlider
|
||||
|
||||
@@ -171,7 +171,7 @@ class QLabeledDoubleSlider(QLabeledSlider):
|
||||
self._label.setDecimals(prec)
|
||||
|
||||
|
||||
class QLabeledRangeSlider(SliderProxy, QAbstractSlider):
|
||||
class QLabeledRangeSlider(_SliderProxy, QAbstractSlider):
|
||||
valueChanged = Signal(tuple)
|
||||
LabelPosition = LabelPosition
|
||||
EdgeLabelMode = EdgeLabelMode
|
@@ -5,9 +5,9 @@ import re
|
||||
from dataclasses import dataclass, replace
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from .qtcompat import PYQT_VERSION
|
||||
from .qtcompat.QtCore import Qt
|
||||
from .qtcompat.QtGui import (
|
||||
from ..qtcompat import PYQT_VERSION
|
||||
from ..qtcompat.QtCore import Qt
|
||||
from ..qtcompat.QtGui import (
|
||||
QBrush,
|
||||
QColor,
|
||||
QGradient,
|
||||
@@ -15,7 +15,7 @@ from .qtcompat.QtGui import (
|
||||
QPalette,
|
||||
QRadialGradient,
|
||||
)
|
||||
from .qtcompat.QtWidgets import QApplication, QSlider, QStyleOptionSlider
|
||||
from ..qtcompat.QtWidgets import QApplication, QSlider, QStyleOptionSlider
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ._generic_range_slider import _GenericRangeSlider
|
||||
@@ -241,7 +241,7 @@ def parse_color(color: str, default_attr) -> QColor | QGradient:
|
||||
# try linear gradient:
|
||||
match = qlineargrad_pattern.search(color)
|
||||
if match:
|
||||
grad = QLinearGradient(*[float(i) for i in match.groups()[:4]])
|
||||
grad = QLinearGradient(*(float(i) for i in match.groups()[:4]))
|
||||
grad.setColorAt(0, QColor(match.groupdict()["stop0"]))
|
||||
grad.setColorAt(1, QColor(match.groupdict()["stop1"]))
|
||||
return grad
|
||||
@@ -249,7 +249,7 @@ def parse_color(color: str, default_attr) -> QColor | QGradient:
|
||||
# try linear gradient:
|
||||
match = qradial_pattern.search(color)
|
||||
if match:
|
||||
grad = QRadialGradient(*[float(i) for i in match.groups()[:5]])
|
||||
grad = QRadialGradient(*(float(i) for i in match.groups()[:5]))
|
||||
grad.setColorAt(0, QColor(match.groupdict()["stop0"]))
|
||||
grad.setColorAt(1, QColor(match.groupdict()["stop1"]))
|
||||
return grad
|
@@ -1,6 +1,6 @@
|
||||
from ..qtcompat.QtCore import Signal
|
||||
from ._generic_range_slider import _GenericRangeSlider
|
||||
from ._generic_slider import _GenericSlider
|
||||
from .qtcompat.QtCore import Signal
|
||||
|
||||
|
||||
class _IntMixin:
|
@@ -4,9 +4,9 @@ from platform import system
|
||||
|
||||
import pytest
|
||||
|
||||
from qtrangeslider.qtcompat import QT_VERSION
|
||||
from qtrangeslider.qtcompat.QtCore import QEvent, QPoint, QPointF, Qt
|
||||
from qtrangeslider.qtcompat.QtGui import QMouseEvent, QWheelEvent
|
||||
from qwidgets.qtcompat import QT_VERSION
|
||||
from qwidgets.qtcompat.QtCore import QEvent, QPoint, QPointF, Qt
|
||||
from qwidgets.qtcompat.QtGui import QMouseEvent, QWheelEvent
|
||||
|
||||
QT_VERSION = LooseVersion(QT_VERSION)
|
||||
|
@@ -2,13 +2,13 @@ import os
|
||||
|
||||
import pytest
|
||||
|
||||
from qtrangeslider import (
|
||||
from qwidgets import (
|
||||
QDoubleRangeSlider,
|
||||
QDoubleSlider,
|
||||
QLabeledDoubleRangeSlider,
|
||||
QLabeledDoubleSlider,
|
||||
)
|
||||
from qtrangeslider.qtcompat import API_NAME
|
||||
from qwidgets.qtcompat import API_NAME
|
||||
|
||||
range_types = {QDoubleRangeSlider, QLabeledDoubleRangeSlider}
|
||||
|
@@ -2,10 +2,10 @@ import math
|
||||
|
||||
import pytest
|
||||
|
||||
from qtrangeslider._generic_slider import _GenericSlider
|
||||
from qtrangeslider.qtcompat.QtCore import QEvent, QPoint, QPointF, Qt
|
||||
from qtrangeslider.qtcompat.QtGui import QHoverEvent
|
||||
from qtrangeslider.qtcompat.QtWidgets import QStyle, QStyleOptionSlider
|
||||
from qwidgets.qtcompat.QtCore import QEvent, QPoint, QPointF, Qt
|
||||
from qwidgets.qtcompat.QtGui import QHoverEvent
|
||||
from qwidgets.qtcompat.QtWidgets import QStyle, QStyleOptionSlider
|
||||
from qwidgets.sliders._generic_slider import _GenericSlider
|
||||
|
||||
from ._testutil import _linspace, _mouse_event, _wheel_event, skip_on_linux_qt6
|
||||
|
@@ -2,10 +2,10 @@ import math
|
||||
|
||||
import pytest
|
||||
|
||||
from qtrangeslider import QDoubleRangeSlider, QRangeSlider
|
||||
from qtrangeslider.qtcompat.QtCore import QEvent, QPoint, QPointF, Qt
|
||||
from qtrangeslider.qtcompat.QtGui import QHoverEvent
|
||||
from qtrangeslider.qtcompat.QtWidgets import QStyle, QStyleOptionSlider
|
||||
from qwidgets import QDoubleRangeSlider, QRangeSlider
|
||||
from qwidgets.qtcompat.QtCore import QEvent, QPoint, QPointF, Qt
|
||||
from qwidgets.qtcompat.QtGui import QHoverEvent
|
||||
from qwidgets.qtcompat.QtWidgets import QStyle, QStyleOptionSlider
|
||||
|
||||
from ._testutil import _linspace, _mouse_event, _wheel_event, skip_on_linux_qt6
|
||||
|
@@ -4,11 +4,11 @@ from distutils.version import LooseVersion
|
||||
|
||||
import pytest
|
||||
|
||||
from qtrangeslider import QDoubleSlider, QLabeledDoubleSlider, QLabeledSlider
|
||||
from qtrangeslider._generic_slider import _GenericSlider
|
||||
from qtrangeslider.qtcompat.QtCore import QEvent, QPoint, QPointF, Qt
|
||||
from qtrangeslider.qtcompat.QtGui import QHoverEvent
|
||||
from qtrangeslider.qtcompat.QtWidgets import QSlider, QStyle, QStyleOptionSlider
|
||||
from qwidgets import QDoubleSlider, QLabeledDoubleSlider, QLabeledSlider
|
||||
from qwidgets.qtcompat.QtCore import QEvent, QPoint, QPointF, Qt
|
||||
from qwidgets.qtcompat.QtGui import QHoverEvent
|
||||
from qwidgets.qtcompat.QtWidgets import QSlider, QStyle, QStyleOptionSlider
|
||||
from qwidgets.sliders._generic_slider import _GenericSlider
|
||||
|
||||
from ._testutil import (
|
||||
QT_VERSION,
|
@@ -2,10 +2,10 @@ import platform
|
||||
|
||||
import pytest
|
||||
|
||||
from qtrangeslider import QRangeSlider
|
||||
from qtrangeslider._generic_range_slider import SC_BAR, SC_HANDLE, SC_NONE
|
||||
from qtrangeslider.qtcompat import API_NAME
|
||||
from qtrangeslider.qtcompat.QtCore import Qt
|
||||
from qwidgets import QRangeSlider
|
||||
from qwidgets.qtcompat import API_NAME
|
||||
from qwidgets.qtcompat.QtCore import Qt
|
||||
from qwidgets.sliders._generic_range_slider import SC_BAR, SC_HANDLE, SC_NONE
|
||||
|
||||
NOT_LINUX = platform.system() != "Linux"
|
||||
NOT_PYSIDE2 = API_NAME != "PySide2"
|
75
setup.cfg
@@ -1,18 +1,13 @@
|
||||
[metadata]
|
||||
name = QtRangeSlider
|
||||
url = https://github.com/tlambert03/QtRangeSlider
|
||||
license = BSD-3
|
||||
license_file = LICENSE
|
||||
description = Multi-handle range slider widget for PyQt/PySide
|
||||
long_description = file: README.md, CHANGELOG.md
|
||||
name = qwidgets
|
||||
description = Missing widgets for PyQt/PySide
|
||||
long_description = file: README.md
|
||||
long_description_content_type = text/markdown
|
||||
url = https://github.com/napari/qwidgets
|
||||
author = Talley Lambert
|
||||
author_email = talley.lambert@gmail.com
|
||||
keywords = qt, range slider, widget
|
||||
project_urls =
|
||||
Source = https://github.com/tlambert03/QtRangeSlider
|
||||
Tracker = https://github.com/tlambert03/QtRangeSlider/issues
|
||||
Changelog = https://github.com/tlambert03/QtRangeSlider/blob/master/CHANGELOG.md
|
||||
license = BSD-3-Clause
|
||||
license_file = LICENSE
|
||||
classifiers =
|
||||
Development Status :: 4 - Beta
|
||||
Environment :: X11 Applications :: Qt
|
||||
@@ -20,49 +15,69 @@ classifiers =
|
||||
License :: OSI Approved :: BSD License
|
||||
Operating System :: OS Independent
|
||||
Programming Language :: Python
|
||||
Programming Language :: Python :: 3
|
||||
Programming Language :: Python :: 3 :: Only
|
||||
Programming Language :: Python :: 3.6
|
||||
Programming Language :: Python :: 3.7
|
||||
Programming Language :: Python :: 3.8
|
||||
Programming Language :: Python :: 3.9
|
||||
Programming Language :: Python :: Implementation :: CPython
|
||||
Topic :: Desktop Environment
|
||||
Topic :: Software Development
|
||||
Topic :: Software Development :: User Interfaces
|
||||
Topic :: Software Development :: Widget Sets
|
||||
keywords = qt, range slider, widget
|
||||
project_urls =
|
||||
Source = https://github.com/napari/qwidgets
|
||||
Tracker = https://github.com/napari/qwidgets/issues
|
||||
Changelog = https://github.com/napari/qwidgets/blob/master/CHANGELOG.md
|
||||
|
||||
[options]
|
||||
zip_safe = False
|
||||
packages = find:
|
||||
python_requires = >=3.6
|
||||
setup_requires = setuptools_scm
|
||||
python_requires = >=3.7
|
||||
setup_requires =
|
||||
setuptools_scm
|
||||
zip_safe = False
|
||||
|
||||
[options.extras_require]
|
||||
pyside2 = pyside2
|
||||
pyqt5 = pyqt5
|
||||
pyside6 = pyside6
|
||||
pyqt6 = pyqt6
|
||||
testing =
|
||||
tox
|
||||
tox-conda
|
||||
pytest
|
||||
pytest-qt
|
||||
pytest-cov
|
||||
dev =
|
||||
ipython
|
||||
jedi<0.18.0
|
||||
isort
|
||||
jedi<0.18.0
|
||||
mypy
|
||||
pre-commit
|
||||
%(testing)s
|
||||
%(pyqt5)s
|
||||
pyside2
|
||||
pytest
|
||||
pytest-cov
|
||||
pytest-qt
|
||||
tox
|
||||
tox-conda
|
||||
pyqt5 =
|
||||
pyqt5
|
||||
pyqt6 =
|
||||
pyqt6
|
||||
pyside2 =
|
||||
pyside2
|
||||
pyside6 =
|
||||
pyside6
|
||||
testing =
|
||||
pytest
|
||||
pytest-cov
|
||||
pytest-qt
|
||||
tox
|
||||
tox-conda
|
||||
|
||||
[flake8]
|
||||
exclude = _version.py,.eggs,examples
|
||||
docstring-convention = numpy
|
||||
ignore = E203,W503,E501,C901,F403,F405
|
||||
ignore = E203,W503,E501,C901,F403,F405,D100
|
||||
|
||||
[pydocstyle]
|
||||
convention = numpy
|
||||
add_select = D402,D415,D417
|
||||
ignore = D100
|
||||
|
||||
[isort]
|
||||
profile=black
|
||||
profile = black
|
||||
|
||||
[tool:pytest]
|
||||
addopts = -W error
|
||||
|
6
setup.py
@@ -1,10 +1,6 @@
|
||||
"""
|
||||
PEP 517 doesn’t support editable installs
|
||||
so this file is currently here to support "pip install -e ."
|
||||
"""
|
||||
from setuptools import setup
|
||||
|
||||
setup(
|
||||
use_scm_version={"write_to": "qtrangeslider/_version.py"},
|
||||
use_scm_version={"write_to": "qwidgets/_version.py"},
|
||||
setup_requires=["setuptools_scm"],
|
||||
)
|
||||
|
14
tox.ini
@@ -3,6 +3,18 @@
|
||||
envlist = py{37,38,39}-{linux,macos,windows}-{pyqt5,pyside2,pyqt6,pyside6},py37-{linux,macos,windows}-{pyqt511,pyside511}
|
||||
toxworkdir=/tmp/.tox
|
||||
|
||||
[coverage:report]
|
||||
exclude_lines =
|
||||
pragma: no cover
|
||||
if TYPE_CHECKING:
|
||||
\.\.\.
|
||||
except ImportError*
|
||||
raise NotImplementedError()
|
||||
omit =
|
||||
qwidgets/_version.py
|
||||
qwidgets/qtcompat/*
|
||||
*_tests*
|
||||
|
||||
[gh-actions]
|
||||
python =
|
||||
3.6: py36
|
||||
@@ -45,4 +57,4 @@ extras =
|
||||
pyside6: pyside6
|
||||
commands_pre =
|
||||
pyqt6,pyside6: pip install -U pytest-qt@git+https://github.com/pytest-dev/pytest-qt.git
|
||||
commands = pytest --color=yes --cov=qtrangeslider --cov-report=xml {posargs}
|
||||
commands = pytest --color=yes --cov=qwidgets --cov-report=xml {posargs}
|
||||
|