mirror of
https://github.com/pyapp-kit/superqt.git
synced 2025-12-16 11:10:06 +01:00
build: drop py38 (#263)
* build: drop py38 * bump min typing ext * ignore cleanup warning from pyside6 * change minreq * bump min * fix for pint again
This commit is contained in:
4
.github/workflows/test_and_deploy.yml
vendored
4
.github/workflows/test_and_deploy.yml
vendored
@@ -68,9 +68,9 @@ jobs:
|
|||||||
test-qt-minreqs:
|
test-qt-minreqs:
|
||||||
uses: pyapp-kit/workflows/.github/workflows/test-pyrepo.yml@v2
|
uses: pyapp-kit/workflows/.github/workflows/test-pyrepo.yml@v2
|
||||||
with:
|
with:
|
||||||
python-version: "3.8"
|
python-version: "3.9"
|
||||||
qt: pyqt5
|
qt: pyqt5
|
||||||
pip-post-installs: "qtpy==1.1.0 typing-extensions==3.7.4.3"
|
pip-post-installs: "qtpy==1.1.0 typing-extensions==4.5.0" # 4.5.0 is just for pint
|
||||||
pip-install-flags: -e
|
pip-install-flags: -e
|
||||||
coverage-upload: artifact
|
coverage-upload: artifact
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ pytest
|
|||||||
|
|
||||||
All widgets must be well-tested, and should work on:
|
All widgets must be well-tested, and should work on:
|
||||||
|
|
||||||
- Python 3.8 and above
|
- Python 3.9 and above
|
||||||
- PyQt5 (5.11 and above) & PyQt6
|
- PyQt5 (5.11 and above) & PyQt6
|
||||||
- PySide2 (5.11 and above) & PySide6
|
- PySide2 (5.11 and above) & PySide6
|
||||||
- macOS, Windows, & Linux
|
- macOS, Windows, & Linux
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ that are not provided in the native QtWidgets module.
|
|||||||
Components are tested on:
|
Components are tested on:
|
||||||
|
|
||||||
- macOS, Windows, & Linux
|
- macOS, Windows, & Linux
|
||||||
- Python 3.8 and above
|
- Python 3.9 and above
|
||||||
- PyQt5 (5.11 and above) & PyQt6
|
- PyQt5 (5.11 and above) & PyQt6
|
||||||
- PySide2 (5.11 and above) & PySide6
|
- PySide2 (5.11 and above) & PySide6
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ QtWidgets module.
|
|||||||
Components are tested on:
|
Components are tested on:
|
||||||
|
|
||||||
- macOS, Windows, & Linux
|
- macOS, Windows, & Linux
|
||||||
- Python 3.8 and above
|
- Python 3.9 and above
|
||||||
- PyQt5 (5.11 and above) & PyQt6
|
- PyQt5 (5.11 and above) & PyQt6
|
||||||
- PySide2 (5.11 and above) & PySide6
|
- PySide2 (5.11 and above) & PySide6
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ SOFTWARE.
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from typing import Deque
|
from collections import deque
|
||||||
|
|
||||||
from qtpy.QtCore import QRect, QSize, Qt, QTimer, Signal
|
from qtpy.QtCore import QRect, QSize, Qt, QTimer, Signal
|
||||||
from qtpy.QtGui import QPainter, QPen
|
from qtpy.QtGui import QPainter, QPen
|
||||||
@@ -65,8 +65,8 @@ class DrawSignalsWidget(QWidget):
|
|||||||
self._scrollTimer.timeout.connect(self._scroll)
|
self._scrollTimer.timeout.connect(self._scroll)
|
||||||
self._scrollTimer.start()
|
self._scrollTimer.start()
|
||||||
|
|
||||||
self._signalActivations: Deque[int] = Deque()
|
self._signalActivations: deque[int] = deque()
|
||||||
self._throttledSignalActivations: Deque[int] = Deque()
|
self._throttledSignalActivations: deque[int] = deque()
|
||||||
|
|
||||||
def sizeHint(self):
|
def sizeHint(self):
|
||||||
return QSize(400, 200)
|
return QSize(400, 200)
|
||||||
@@ -84,7 +84,7 @@ class DrawSignalsWidget(QWidget):
|
|||||||
|
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def scrollAndCut(self, v: Deque[int], cutoff: int):
|
def scrollAndCut(self, v: deque[int], cutoff: int):
|
||||||
L = len(v)
|
L = len(v)
|
||||||
for p in range(L):
|
for p in range(L):
|
||||||
v[p] += 1
|
v[p] += 1
|
||||||
@@ -121,7 +121,7 @@ class DrawSignalsWidget(QWidget):
|
|||||||
p.drawLine(0, h2, w, h2)
|
p.drawLine(0, h2, w, h2)
|
||||||
p.restore()
|
p.restore()
|
||||||
|
|
||||||
def _drawSignals(self, p: QPainter, v: Deque[int], color, yStart, yEnd):
|
def _drawSignals(self, p: QPainter, v: deque[int], color, yStart, yEnd):
|
||||||
p.save()
|
p.save()
|
||||||
pen = QPen()
|
pen = QPen()
|
||||||
pen.setWidthF(2.0)
|
pen.setWidthF(2.0)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ build-backend = "hatchling.build"
|
|||||||
name = "superqt"
|
name = "superqt"
|
||||||
description = "Missing widgets and components for PyQt/PySide"
|
description = "Missing widgets and components for PyQt/PySide"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.8"
|
requires-python = ">=3.9"
|
||||||
license = { text = "BSD 3-Clause License" }
|
license = { text = "BSD 3-Clause License" }
|
||||||
authors = [{ email = "talley.lambert@gmail.com", name = "Talley Lambert" }]
|
authors = [{ email = "talley.lambert@gmail.com", name = "Talley Lambert" }]
|
||||||
keywords = [
|
keywords = [
|
||||||
@@ -28,7 +28,6 @@ classifiers = [
|
|||||||
"Operating System :: OS Independent",
|
"Operating System :: OS Independent",
|
||||||
"Programming Language :: Python :: 3",
|
"Programming Language :: Python :: 3",
|
||||||
"Programming Language :: Python :: 3 :: Only",
|
"Programming Language :: Python :: 3 :: Only",
|
||||||
"Programming Language :: Python :: 3.8",
|
|
||||||
"Programming Language :: Python :: 3.9",
|
"Programming Language :: Python :: 3.9",
|
||||||
"Programming Language :: Python :: 3.10",
|
"Programming Language :: Python :: 3.10",
|
||||||
"Programming Language :: Python :: 3.11",
|
"Programming Language :: Python :: 3.11",
|
||||||
@@ -41,13 +40,21 @@ dynamic = ["version"]
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"pygments>=2.4.0",
|
"pygments>=2.4.0",
|
||||||
"qtpy>=1.1.0",
|
"qtpy>=1.1.0",
|
||||||
"typing-extensions >=3.7.4.3,!=3.10.0.0",
|
"typing-extensions >=3.7.4.3,!=3.10.0.0", # however, pint requires >4.5.0
|
||||||
]
|
]
|
||||||
|
|
||||||
# extras
|
# extras
|
||||||
# https://peps.python.org/pep-0621/#dependencies-optional-dependencies
|
# https://peps.python.org/pep-0621/#dependencies-optional-dependencies
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
test = ["pint", "pytest", "pytest-cov", "pytest-qt", "numpy", "cmap", "pyconify"]
|
test = [
|
||||||
|
"pint",
|
||||||
|
"pytest",
|
||||||
|
"pytest-cov",
|
||||||
|
"pytest-qt",
|
||||||
|
"numpy",
|
||||||
|
"cmap",
|
||||||
|
"pyconify",
|
||||||
|
]
|
||||||
dev = [
|
dev = [
|
||||||
"ipython",
|
"ipython",
|
||||||
"ruff",
|
"ruff",
|
||||||
@@ -58,7 +65,13 @@ dev = [
|
|||||||
"rich",
|
"rich",
|
||||||
"types-Pygments",
|
"types-Pygments",
|
||||||
]
|
]
|
||||||
docs = ["mkdocs-macros-plugin", "mkdocs-material", "mkdocstrings[python]", "pint", "cmap"]
|
docs = [
|
||||||
|
"mkdocs-macros-plugin",
|
||||||
|
"mkdocs-material",
|
||||||
|
"mkdocstrings[python]",
|
||||||
|
"pint",
|
||||||
|
"cmap",
|
||||||
|
]
|
||||||
quantity = ["pint"]
|
quantity = ["pint"]
|
||||||
cmap = ["cmap >=0.1.1"]
|
cmap = ["cmap >=0.1.1"]
|
||||||
pyside2 = ["pyside2"]
|
pyside2 = ["pyside2"]
|
||||||
@@ -100,21 +113,30 @@ python = ["3.11"]
|
|||||||
|
|
||||||
[[tool.hatch.envs.test.matrix]]
|
[[tool.hatch.envs.test.matrix]]
|
||||||
qt = ["pyside2", "pyqt5", "pyqt5.12"]
|
qt = ["pyside2", "pyqt5", "pyqt5.12"]
|
||||||
python = ["3.8"]
|
python = ["3.9"]
|
||||||
|
|
||||||
[tool.hatch.envs.test.overrides]
|
[tool.hatch.envs.test.overrides]
|
||||||
matrix.qt.extra-dependencies = [
|
matrix.qt.extra-dependencies = [
|
||||||
{value = "pyside2", if = ["pyside2"]},
|
{ value = "pyside2", if = [
|
||||||
{value = "pyside6", if = ["pyside6"]},
|
"pyside2",
|
||||||
{value = "pyqt5", if = ["pyqt5"]},
|
] },
|
||||||
{value = "pyqt6", if = ["pyqt6"]},
|
{ value = "pyside6", if = [
|
||||||
{value = "pyqt5==5.12", if = ["pyqt5.12"]},
|
"pyside6",
|
||||||
|
] },
|
||||||
|
{ value = "pyqt5", if = [
|
||||||
|
"pyqt5",
|
||||||
|
] },
|
||||||
|
{ value = "pyqt6", if = [
|
||||||
|
"pyqt6",
|
||||||
|
] },
|
||||||
|
{ value = "pyqt5==5.12", if = [
|
||||||
|
"pyqt5.12",
|
||||||
|
] },
|
||||||
]
|
]
|
||||||
|
|
||||||
# https://github.com/charliermarsh/ruff
|
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
line-length = 88
|
line-length = 88
|
||||||
target-version = "py38"
|
target-version = "py39"
|
||||||
src = ["src", "tests"]
|
src = ["src", "tests"]
|
||||||
|
|
||||||
# https://docs.astral.sh/ruff/rules
|
# https://docs.astral.sh/ruff/rules
|
||||||
@@ -132,7 +154,7 @@ select = [
|
|||||||
"B", # flake8-bugbear
|
"B", # flake8-bugbear
|
||||||
"A001", # flake8-builtins
|
"A001", # flake8-builtins
|
||||||
"RUF", # ruff-specific rules
|
"RUF", # ruff-specific rules
|
||||||
"TCH", # flake8-type-checking
|
"TC", # flake8-type-checking
|
||||||
"TID", # flake8-tidy-imports
|
"TID", # flake8-tidy-imports
|
||||||
]
|
]
|
||||||
ignore = [
|
ignore = [
|
||||||
@@ -159,6 +181,7 @@ filterwarnings = [
|
|||||||
"ignore:QPixmapCache.find:DeprecationWarning:",
|
"ignore:QPixmapCache.find:DeprecationWarning:",
|
||||||
"ignore:SelectableGroups dict interface:DeprecationWarning",
|
"ignore:SelectableGroups dict interface:DeprecationWarning",
|
||||||
"ignore:The distutils package is deprecated:DeprecationWarning",
|
"ignore:The distutils package is deprecated:DeprecationWarning",
|
||||||
|
"ignore:.*Skipping callback call set_result",
|
||||||
]
|
]
|
||||||
|
|
||||||
# https://mypy.readthedocs.io/en/stable/config_file.html
|
# https://mypy.readthedocs.io/en/stable/config_file.html
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Container
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from cmap import Colormap
|
from cmap import Colormap
|
||||||
from qtpy.QtCore import Qt, Signal
|
from qtpy.QtCore import Qt, Signal
|
||||||
@@ -11,6 +11,8 @@ from ._cmap_line_edit import QColormapLineEdit
|
|||||||
from ._cmap_utils import try_cast_colormap
|
from ._cmap_utils import try_cast_colormap
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
from collections.abc import Container
|
||||||
|
|
||||||
from cmap._catalog import Category, Interpolation
|
from cmap._catalog import Category, Interpolation
|
||||||
from qtpy.QtGui import QKeyEvent
|
from qtpy.QtGui import QKeyEvent
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Any, Sequence
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
from cmap import Colormap
|
from cmap import Colormap
|
||||||
from qtpy.QtCore import Qt, Signal
|
from qtpy.QtCore import Qt, Signal
|
||||||
@@ -23,6 +23,8 @@ from ._cmap_line_edit import QColormapLineEdit
|
|||||||
from ._cmap_utils import try_cast_colormap
|
from ._cmap_utils import try_cast_colormap
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
from collections.abc import Sequence
|
||||||
|
|
||||||
from cmap._colormap import ColorStopsLike
|
from cmap._colormap import ColorStopsLike
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|||||||
import warnings
|
import warnings
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
from enum import IntEnum, auto
|
from enum import IntEnum, auto
|
||||||
from typing import Any, Literal, Sequence, cast
|
from typing import TYPE_CHECKING, Any, Literal, cast
|
||||||
|
|
||||||
from qtpy.QtCore import QModelIndex, QPersistentModelIndex, QRect, QSize, Qt, Signal
|
from qtpy.QtCore import QModelIndex, QPersistentModelIndex, QRect, QSize, Qt, Signal
|
||||||
from qtpy.QtGui import QColor, QPainter
|
from qtpy.QtGui import QColor, QPainter
|
||||||
@@ -19,6 +19,9 @@ from qtpy.QtWidgets import (
|
|||||||
|
|
||||||
from superqt.utils import signals_blocked
|
from superqt.utils import signals_blocked
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from collections.abc import Sequence
|
||||||
|
|
||||||
_NAME_MAP = {QColor(x).name(): x for x in QColor.colorNames()}
|
_NAME_MAP = {QColor(x).name(): x for x in QColor.colorNames()}
|
||||||
|
|
||||||
COLOR_ROLE = Qt.ItemDataRole.BackgroundRole
|
COLOR_ROLE = Qt.ItemDataRole.BackgroundRole
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from enum import Enum, EnumMeta, Flag
|
|||||||
from functools import reduce
|
from functools import reduce
|
||||||
from itertools import combinations
|
from itertools import combinations
|
||||||
from operator import or_
|
from operator import or_
|
||||||
from typing import Optional, Tuple, TypeVar
|
from typing import Optional, TypeVar
|
||||||
|
|
||||||
from qtpy.QtCore import Signal
|
from qtpy.QtCore import Signal
|
||||||
from qtpy.QtWidgets import QComboBox
|
from qtpy.QtWidgets import QComboBox
|
||||||
@@ -47,7 +47,7 @@ def _get_name(enum_value: Enum):
|
|||||||
return name
|
return name
|
||||||
|
|
||||||
|
|
||||||
def _get_name_with_value(enum_value: Enum) -> Tuple[str, Enum]:
|
def _get_name_with_value(enum_value: Enum) -> tuple[str, Enum]:
|
||||||
return _get_name(enum_value), enum_value
|
return _get_name(enum_value), enum_value
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
from typing import List
|
|
||||||
|
|
||||||
from qtpy.QtCore import Qt
|
from qtpy.QtCore import Qt
|
||||||
from qtpy.QtGui import QFont, QFontMetrics, QTextLayout
|
from qtpy.QtGui import QFont, QFontMetrics, QTextLayout
|
||||||
|
|
||||||
@@ -36,7 +34,7 @@ class _GenericEliding:
|
|||||||
self._ellipses_width = width
|
self._ellipses_width = width
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def wrapText(text, width, font=None) -> List[str]:
|
def wrapText(text, width, font=None) -> list[str]:
|
||||||
"""Returns `text`, split as it would be wrapped for `width`, given `font`.
|
"""Returns `text`, split as it would be wrapped for `width`, given `font`.
|
||||||
|
|
||||||
Static method.
|
Static method.
|
||||||
@@ -74,5 +72,5 @@ class _GenericEliding:
|
|||||||
# join them
|
# join them
|
||||||
return "".join(text[:nlines] + [last_line])
|
return "".join(text[:nlines] + [last_line])
|
||||||
|
|
||||||
def _wrappedText(self) -> List[str]:
|
def _wrappedText(self) -> list[str]:
|
||||||
return _GenericEliding.wrapText(self._text, self.width(), self.font())
|
return _GenericEliding.wrapText(self._text, self.width(), self.font())
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
from typing import Mapping, Type, Union
|
from collections.abc import Mapping
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
FONTFILE_ATTR = "__font_file__"
|
FONTFILE_ATTR = "__font_file__"
|
||||||
|
|
||||||
@@ -69,7 +70,7 @@ class IconFont(metaclass=IconFontMeta):
|
|||||||
__font_file__ = "..."
|
__font_file__ = "..."
|
||||||
|
|
||||||
|
|
||||||
def namespace2font(namespace: Union[Mapping, Type], name: str) -> Type[IconFont]:
|
def namespace2font(namespace: Union[Mapping, type], name: str) -> type[IconFont]:
|
||||||
"""Convenience to convert a namespace (class, module, dict) into an IconFont."""
|
"""Convenience to convert a namespace (class, module, dict) into an IconFont."""
|
||||||
if isinstance(namespace, type):
|
if isinstance(namespace, type):
|
||||||
if not isinstance(getattr(namespace, FONTFILE_ATTR), str):
|
if not isinstance(getattr(namespace, FONTFILE_ATTR), str):
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import contextlib
|
import contextlib
|
||||||
from typing import ClassVar, Dict, List, Set, Tuple
|
from typing import ClassVar
|
||||||
|
|
||||||
from ._iconfont import IconFontMeta, namespace2font
|
from ._iconfont import IconFontMeta, namespace2font
|
||||||
|
|
||||||
@@ -11,9 +11,9 @@ except ImportError:
|
|||||||
|
|
||||||
class FontIconManager:
|
class FontIconManager:
|
||||||
ENTRY_POINT: ClassVar[str] = "superqt.fonticon"
|
ENTRY_POINT: ClassVar[str] = "superqt.fonticon"
|
||||||
_PLUGINS: ClassVar[Dict[str, EntryPoint]] = {}
|
_PLUGINS: ClassVar[dict[str, EntryPoint]] = {}
|
||||||
_LOADED: ClassVar[Dict[str, IconFontMeta]] = {}
|
_LOADED: ClassVar[dict[str, IconFontMeta]] = {}
|
||||||
_BLOCKED: ClassVar[Set[EntryPoint]] = set()
|
_BLOCKED: ClassVar[set[EntryPoint]] = set()
|
||||||
|
|
||||||
def _discover_fonts(self) -> None:
|
def _discover_fonts(self) -> None:
|
||||||
self._PLUGINS.clear()
|
self._PLUGINS.clear()
|
||||||
@@ -86,15 +86,15 @@ _manager = FontIconManager()
|
|||||||
get_font_class = _manager._get_font_class
|
get_font_class = _manager._get_font_class
|
||||||
|
|
||||||
|
|
||||||
def discover() -> Tuple[str]:
|
def discover() -> tuple[str]:
|
||||||
_manager._discover_fonts()
|
_manager._discover_fonts()
|
||||||
|
|
||||||
|
|
||||||
def available() -> Tuple[str]:
|
def available() -> tuple[str]:
|
||||||
return tuple(_manager._PLUGINS)
|
return tuple(_manager._PLUGINS)
|
||||||
|
|
||||||
|
|
||||||
def loaded(load_all=False) -> Dict[str, List[str]]:
|
def loaded(load_all=False) -> dict[str, list[str]]:
|
||||||
if load_all:
|
if load_all:
|
||||||
discover()
|
discover()
|
||||||
for x in available():
|
for x in available():
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
from collections import abc, defaultdict
|
from collections import abc, defaultdict
|
||||||
|
from collections.abc import Sequence
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import TYPE_CHECKING, ClassVar, DefaultDict, Sequence, Tuple, Union, cast
|
from typing import TYPE_CHECKING, ClassVar, Union, cast
|
||||||
|
|
||||||
from qtpy import QT_VERSION
|
from qtpy import QT_VERSION
|
||||||
from qtpy.QtCore import QObject, QPoint, QRect, QSize, Qt
|
from qtpy.QtCore import QObject, QPoint, QRect, QSize, Qt
|
||||||
@@ -47,8 +48,8 @@ ValidColor = Union[
|
|||||||
int,
|
int,
|
||||||
str,
|
str,
|
||||||
Qt.GlobalColor,
|
Qt.GlobalColor,
|
||||||
Tuple[int, int, int, int],
|
tuple[int, int, int, int],
|
||||||
Tuple[int, int, int],
|
tuple[int, int, int],
|
||||||
None,
|
None,
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -159,7 +160,7 @@ class _QFontIconEngine(QIconEngine):
|
|||||||
def __init__(self, options: _IconOptions):
|
def __init__(self, options: _IconOptions):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self._opts: defaultdict[QIcon.State, dict[QIcon.Mode, _IconOptions | None]] = (
|
self._opts: defaultdict[QIcon.State, dict[QIcon.Mode, _IconOptions | None]] = (
|
||||||
DefaultDict(dict)
|
defaultdict(dict)
|
||||||
)
|
)
|
||||||
self._opts[QIcon.State.Off][QIcon.Mode.Normal] = options
|
self._opts[QIcon.State.Off][QIcon.Mode.Normal] = options
|
||||||
self.update_hash()
|
self.update_hash()
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import logging
|
import logging
|
||||||
from typing import Any, Iterable, Mapping
|
from collections.abc import Iterable, Mapping
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from qtpy.QtCore import QRegularExpression
|
from qtpy.QtCore import QRegularExpression
|
||||||
from qtpy.QtWidgets import QLineEdit, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
|
from qtpy.QtWidgets import QLineEdit, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
from typing import List, Optional, Sequence, Tuple, TypeVar, Union
|
from collections.abc import Sequence
|
||||||
|
from typing import Optional, TypeVar, Union
|
||||||
|
|
||||||
from qtpy import QtGui
|
from qtpy import QtGui
|
||||||
from qtpy.QtCore import Property, QEvent, QPoint, QPointF, QRect, QRectF, Qt, Signal
|
from qtpy.QtCore import Property, QEvent, QPoint, QPointF, QRect, QRectF, Qt, Signal
|
||||||
@@ -42,11 +43,11 @@ class _GenericRangeSlider(_GenericSlider):
|
|||||||
self.valueChanged = self._valuesChanged
|
self.valueChanged = self._valuesChanged
|
||||||
self.sliderMoved = self._slidersMoved
|
self.sliderMoved = self._slidersMoved
|
||||||
# list of values
|
# list of values
|
||||||
self._value: List[_T] = [20, 80]
|
self._value: list[_T] = [20, 80]
|
||||||
|
|
||||||
# list of current positions of each handle. same length as _value
|
# list of current positions of each handle. same length as _value
|
||||||
# If tracking is enabled (the default) this will be identical to _value
|
# If tracking is enabled (the default) this will be identical to _value
|
||||||
self._position: List[_T] = [20, 80]
|
self._position: list[_T] = [20, 80]
|
||||||
|
|
||||||
# which handle is being pressed/hovered
|
# which handle is being pressed/hovered
|
||||||
self._pressedIndex = 0
|
self._pressedIndex = 0
|
||||||
@@ -113,7 +114,7 @@ class _GenericRangeSlider(_GenericSlider):
|
|||||||
|
|
||||||
# ############### QtOverrides #######################
|
# ############### QtOverrides #######################
|
||||||
|
|
||||||
def value(self) -> Tuple[_T, ...]:
|
def value(self) -> tuple[_T, ...]:
|
||||||
"""Get current value of the widget as a tuple of integers."""
|
"""Get current value of the widget as a tuple of integers."""
|
||||||
return tuple(self._value)
|
return tuple(self._value)
|
||||||
|
|
||||||
@@ -332,7 +333,7 @@ class _GenericRangeSlider(_GenericSlider):
|
|||||||
# NOTE: this is very much tied to mousepress... not a generic "get control"
|
# NOTE: this is very much tied to mousepress... not a generic "get control"
|
||||||
def _getControlAtPos(
|
def _getControlAtPos(
|
||||||
self, pos: QPoint, opt: Optional[QStyleOptionSlider] = None
|
self, pos: QPoint, opt: Optional[QStyleOptionSlider] = None
|
||||||
) -> Tuple[QStyle.SubControl, int]:
|
) -> tuple[QStyle.SubControl, int]:
|
||||||
"""Update self._pressedControl based on ev.pos()."""
|
"""Update self._pressedControl based on ev.pos()."""
|
||||||
opt = opt or self._styleOption
|
opt = opt or self._styleOption
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|||||||
import contextlib
|
import contextlib
|
||||||
from enum import IntEnum, IntFlag, auto
|
from enum import IntEnum, IntFlag, auto
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from typing import Any, Iterable, overload
|
from typing import TYPE_CHECKING, Any, overload
|
||||||
|
|
||||||
from qtpy import QtGui
|
from qtpy import QtGui
|
||||||
from qtpy.QtCore import Property, QPoint, QSize, Qt, Signal
|
from qtpy.QtCore import Property, QPoint, QSize, Qt, Signal
|
||||||
@@ -25,6 +25,9 @@ from superqt.utils import signals_blocked
|
|||||||
|
|
||||||
from ._sliders import QDoubleRangeSlider, QDoubleSlider, QRangeSlider
|
from ._sliders import QDoubleRangeSlider, QDoubleSlider, QRangeSlider
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from collections.abc import Iterable
|
||||||
|
|
||||||
|
|
||||||
class LabelPosition(IntEnum):
|
class LabelPosition(IntEnum):
|
||||||
NoLabel = 0
|
NoLabel = 0
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
from collections.abc import Iterator
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from typing import TYPE_CHECKING, Iterator
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from qtpy.QtCore import QObject
|
from qtpy.QtCore import QObject
|
||||||
|
|||||||
@@ -9,9 +9,7 @@ from typing import (
|
|||||||
Any,
|
Any,
|
||||||
Callable,
|
Callable,
|
||||||
ClassVar,
|
ClassVar,
|
||||||
Generator,
|
|
||||||
Generic,
|
Generic,
|
||||||
Sequence,
|
|
||||||
TypeVar,
|
TypeVar,
|
||||||
overload,
|
overload,
|
||||||
)
|
)
|
||||||
@@ -19,6 +17,8 @@ from typing import (
|
|||||||
from qtpy.QtCore import QObject, QRunnable, QThread, QThreadPool, QTimer, Signal
|
from qtpy.QtCore import QObject, QRunnable, QThread, QThreadPool, QTimer, Signal
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
from collections.abc import Generator, Sequence
|
||||||
|
|
||||||
_T = TypeVar("_T")
|
_T = TypeVar("_T")
|
||||||
|
|
||||||
class SigInst(Generic[_T]):
|
class SigInst(Generic[_T]):
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
from typing import List, Tuple
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from pytestqt.qtbot import QtBot
|
from pytestqt.qtbot import QtBot
|
||||||
from qtpy.QtCore import Qt
|
from qtpy.QtCore import Qt
|
||||||
@@ -30,15 +28,15 @@ def widget(qtbot: QtBot, data: dict) -> QSearchableTreeWidget:
|
|||||||
return widget
|
return widget
|
||||||
|
|
||||||
|
|
||||||
def columns(item: QTreeWidgetItem) -> Tuple[str, str]:
|
def columns(item: QTreeWidgetItem) -> tuple[str, str]:
|
||||||
return item.text(0), item.text(1)
|
return item.text(0), item.text(1)
|
||||||
|
|
||||||
|
|
||||||
def all_items(tree: QTreeWidget) -> List[QTreeWidgetItem]:
|
def all_items(tree: QTreeWidget) -> list[QTreeWidgetItem]:
|
||||||
return tree.findItems("", Qt.MatchContains | Qt.MatchRecursive)
|
return tree.findItems("", Qt.MatchContains | Qt.MatchRecursive)
|
||||||
|
|
||||||
|
|
||||||
def shown_items(tree: QTreeWidget) -> List[QTreeWidgetItem]:
|
def shown_items(tree: QTreeWidget) -> list[QTreeWidgetItem]:
|
||||||
items = all_items(tree)
|
items = all_items(tree)
|
||||||
return [item for item in items if not item.isHidden()]
|
return [item for item in items if not item.isHidden()]
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
from typing import Any, Iterable
|
from collections.abc import Iterable
|
||||||
|
from typing import Any
|
||||||
from unittest.mock import Mock
|
from unittest.mock import Mock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import math
|
import math
|
||||||
|
from collections.abc import Iterable
|
||||||
from itertools import product
|
from itertools import product
|
||||||
from typing import Any, Iterable
|
from typing import Any
|
||||||
from unittest.mock import Mock
|
from unittest.mock import Mock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|||||||
Reference in New Issue
Block a user