Compare commits
2 Commits
v1.0.0
...
ceba71927d
| Author | SHA1 | Date | |
|---|---|---|---|
| ceba71927d | |||
| ac678e8dce |
11
README.md
11
README.md
@@ -43,6 +43,17 @@ with dpg.window(label="Engine"):
|
|||||||
dpgg.status_light(tag="ecu", label="ECU", state=True)
|
dpgg.status_light(tag="ecu", label="ECU", state=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Gauges also accept Dear PyGui's usual `parent` argument for adding a gauge to an
|
||||||
|
existing container after that container has already been created:
|
||||||
|
|
||||||
|
```python
|
||||||
|
dpg.add_window(tag="data_input", label="Data Input")
|
||||||
|
dpgg.analog_gauge(tag="rpm", parent="data_input", label="RPM")
|
||||||
|
```
|
||||||
|
|
||||||
|
The `parent` is applied to the gauge's outer group. The gauge's internal drawlist
|
||||||
|
is then parented to that group.
|
||||||
|
|
||||||
## GUI-Thread Contract
|
## GUI-Thread Contract
|
||||||
|
|
||||||
Dear PyGui item operations must happen on the GUI thread. Gauge creation and runtime updates such as
|
Dear PyGui item operations must happen on the GUI thread. Gauge creation and runtime updates such as
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "dpg-gauges"
|
name = "dpg-gauges"
|
||||||
version = "1.0.0"
|
version = "1.0.2"
|
||||||
description = "Dear PyGui gauge widgets for dashboards and telemetry displays"
|
description = "Dear PyGui gauge widgets for dashboards and telemetry displays"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
authors = [
|
authors = [
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ from .types import (
|
|||||||
ThresholdBand,
|
ThresholdBand,
|
||||||
)
|
)
|
||||||
|
|
||||||
__version__ = "1.0.0"
|
__version__ = "1.0.2"
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"configure",
|
"configure",
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from . import widget as _widget
|
|
||||||
from .gauges import GaugeConfig
|
from .gauges import GaugeConfig
|
||||||
from .state import (
|
from .state import (
|
||||||
configure_gauges,
|
configure_gauges,
|
||||||
@@ -17,6 +16,44 @@ from .state import (
|
|||||||
update_runtime_gauge,
|
update_runtime_gauge,
|
||||||
)
|
)
|
||||||
from .types import GaugeMarker, GaugeValue, Tag, ThresholdBand
|
from .types import GaugeMarker, GaugeValue, Tag, ThresholdBand
|
||||||
|
from .widget import (
|
||||||
|
analog_gauge,
|
||||||
|
bar_gauge,
|
||||||
|
battery_gauge,
|
||||||
|
compass_gauge,
|
||||||
|
digital_gauge,
|
||||||
|
gauge_grid,
|
||||||
|
gauge_panel,
|
||||||
|
level_gauge,
|
||||||
|
multi_value_gauge,
|
||||||
|
segmented_gauge,
|
||||||
|
status_light,
|
||||||
|
thermometer_gauge,
|
||||||
|
)
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"analog_gauge",
|
||||||
|
"bar_gauge",
|
||||||
|
"battery_gauge",
|
||||||
|
"compass_gauge",
|
||||||
|
"configure",
|
||||||
|
"configure_gauge",
|
||||||
|
"delete_gauge",
|
||||||
|
"digital_gauge",
|
||||||
|
"gauge_grid",
|
||||||
|
"gauge_panel",
|
||||||
|
"get_value",
|
||||||
|
"level_gauge",
|
||||||
|
"multi_value_gauge",
|
||||||
|
"segmented_gauge",
|
||||||
|
"set_markers",
|
||||||
|
"set_show",
|
||||||
|
"set_thresholds",
|
||||||
|
"set_value",
|
||||||
|
"status_light",
|
||||||
|
"thermometer_gauge",
|
||||||
|
"update_gauge",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def configure(**config: Any) -> None:
|
def configure(**config: Any) -> None:
|
||||||
@@ -24,20 +61,6 @@ def configure(**config: Any) -> None:
|
|||||||
configure_gauges(**config)
|
configure_gauges(**config)
|
||||||
|
|
||||||
|
|
||||||
analog_gauge = _widget.analog_gauge
|
|
||||||
digital_gauge = _widget.digital_gauge
|
|
||||||
bar_gauge = _widget.bar_gauge
|
|
||||||
level_gauge = _widget.level_gauge
|
|
||||||
status_light = _widget.status_light
|
|
||||||
segmented_gauge = _widget.segmented_gauge
|
|
||||||
compass_gauge = _widget.compass_gauge
|
|
||||||
thermometer_gauge = _widget.thermometer_gauge
|
|
||||||
battery_gauge = _widget.battery_gauge
|
|
||||||
multi_value_gauge = _widget.multi_value_gauge
|
|
||||||
gauge_panel = _widget.gauge_panel
|
|
||||||
gauge_grid = _widget.gauge_grid
|
|
||||||
|
|
||||||
|
|
||||||
def set_value(tag: Tag, value: GaugeValue) -> None:
|
def set_value(tag: Tag, value: GaugeValue) -> None:
|
||||||
"""Set a gauge target value from the Dear PyGui GUI thread."""
|
"""Set a gauge target value from the Dear PyGui GUI thread."""
|
||||||
set_runtime_value(tag, value)
|
set_runtime_value(tag, value)
|
||||||
@@ -78,4 +101,4 @@ def delete_gauge(tag: Tag) -> None:
|
|||||||
delete_runtime_gauge(tag)
|
delete_runtime_gauge(tag)
|
||||||
|
|
||||||
|
|
||||||
__all_configs__ = (GaugeConfig,)
|
__all_configs__: tuple[type[GaugeConfig], ...] = (GaugeConfig,)
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ def _normalize_smoothing(value: SmoothingConfig | bool | None) -> SmoothingConfi
|
|||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class GaugeConfig:
|
class GaugeConfig:
|
||||||
tag: Tag | None = None
|
tag: Tag | None = None
|
||||||
|
parent: Tag | None = None
|
||||||
label: str | None = None
|
label: str | None = None
|
||||||
value: GaugeValue = None
|
value: GaugeValue = None
|
||||||
min_value: float = 0.0
|
min_value: float = 0.0
|
||||||
|
|||||||
0
src/dpg_gauges/py.typed
Normal file
0
src/dpg_gauges/py.typed
Normal file
@@ -50,7 +50,7 @@ class GaugeRenderer:
|
|||||||
|
|
||||||
def __init__(self, state: GaugeState) -> None:
|
def __init__(self, state: GaugeState) -> None:
|
||||||
self.state = state
|
self.state = state
|
||||||
self.layers = DrawLayers()
|
self.layers: DrawLayers = DrawLayers()
|
||||||
self._scheduled = False
|
self._scheduled = False
|
||||||
|
|
||||||
def render(self) -> None:
|
def render(self) -> None:
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ def create_gauge_context(gauge_type: str, config: ConfigT) -> GaugeContext[Confi
|
|||||||
|
|
||||||
container = dpg.add_group(
|
container = dpg.add_group(
|
||||||
tag=container_tag or 0,
|
tag=container_tag or 0,
|
||||||
|
parent=config.parent or 0,
|
||||||
width=width,
|
width=width,
|
||||||
height=height,
|
height=height,
|
||||||
show=config.show,
|
show=config.show,
|
||||||
@@ -153,6 +154,7 @@ def create_gauge_context(gauge_type: str, config: ConfigT) -> GaugeContext[Confi
|
|||||||
def gauge_panel(
|
def gauge_panel(
|
||||||
*,
|
*,
|
||||||
tag: Tag | None = None,
|
tag: Tag | None = None,
|
||||||
|
parent: Tag | None = None,
|
||||||
label: str | None = None,
|
label: str | None = None,
|
||||||
width: int = 0,
|
width: int = 0,
|
||||||
height: int = 0,
|
height: int = 0,
|
||||||
@@ -168,6 +170,7 @@ def gauge_panel(
|
|||||||
return LayoutContext(None)
|
return LayoutContext(None)
|
||||||
container = dpg.add_child_window(
|
container = dpg.add_child_window(
|
||||||
tag=tag or 0,
|
tag=tag or 0,
|
||||||
|
parent=parent or 0,
|
||||||
label=label or "",
|
label=label or "",
|
||||||
width=width,
|
width=width,
|
||||||
height=height,
|
height=height,
|
||||||
@@ -185,6 +188,7 @@ def gauge_grid(
|
|||||||
*,
|
*,
|
||||||
columns: int = 1,
|
columns: int = 1,
|
||||||
tag: Tag | None = None,
|
tag: Tag | None = None,
|
||||||
|
parent: Tag | None = None,
|
||||||
width: int = 0,
|
width: int = 0,
|
||||||
height: int = 0,
|
height: int = 0,
|
||||||
show: bool = True,
|
show: bool = True,
|
||||||
@@ -196,6 +200,7 @@ def gauge_grid(
|
|||||||
columns = max(int(columns), 1)
|
columns = max(int(columns), 1)
|
||||||
container = dpg.add_group(
|
container = dpg.add_group(
|
||||||
tag=tag or 0,
|
tag=tag or 0,
|
||||||
|
parent=parent or 0,
|
||||||
width=width,
|
width=width,
|
||||||
height=height,
|
height=height,
|
||||||
show=show,
|
show=show,
|
||||||
@@ -208,6 +213,7 @@ def gauge_grid(
|
|||||||
def analog_gauge(
|
def analog_gauge(
|
||||||
*,
|
*,
|
||||||
tag: Tag | None = None,
|
tag: Tag | None = None,
|
||||||
|
parent: Tag | None = None,
|
||||||
label: str | None = None,
|
label: str | None = None,
|
||||||
value: GaugeValue = None,
|
value: GaugeValue = None,
|
||||||
min_value: float = 0.0,
|
min_value: float = 0.0,
|
||||||
@@ -253,6 +259,7 @@ def analog_gauge(
|
|||||||
def digital_gauge(
|
def digital_gauge(
|
||||||
*,
|
*,
|
||||||
tag: Tag | None = None,
|
tag: Tag | None = None,
|
||||||
|
parent: Tag | None = None,
|
||||||
label: str | None = None,
|
label: str | None = None,
|
||||||
value: GaugeValue = None,
|
value: GaugeValue = None,
|
||||||
min_value: float = 0.0,
|
min_value: float = 0.0,
|
||||||
@@ -287,6 +294,7 @@ def digital_gauge(
|
|||||||
def bar_gauge(
|
def bar_gauge(
|
||||||
*,
|
*,
|
||||||
tag: Tag | None = None,
|
tag: Tag | None = None,
|
||||||
|
parent: Tag | None = None,
|
||||||
label: str | None = None,
|
label: str | None = None,
|
||||||
value: GaugeValue = None,
|
value: GaugeValue = None,
|
||||||
min_value: float = 0.0,
|
min_value: float = 0.0,
|
||||||
@@ -326,6 +334,7 @@ def bar_gauge(
|
|||||||
def level_gauge(
|
def level_gauge(
|
||||||
*,
|
*,
|
||||||
tag: Tag | None = None,
|
tag: Tag | None = None,
|
||||||
|
parent: Tag | None = None,
|
||||||
label: str | None = None,
|
label: str | None = None,
|
||||||
value: GaugeValue = None,
|
value: GaugeValue = None,
|
||||||
min_value: float = 0.0,
|
min_value: float = 0.0,
|
||||||
@@ -365,6 +374,7 @@ def level_gauge(
|
|||||||
def status_light(
|
def status_light(
|
||||||
*,
|
*,
|
||||||
tag: Tag | None = None,
|
tag: Tag | None = None,
|
||||||
|
parent: Tag | None = None,
|
||||||
label: str | None = None,
|
label: str | None = None,
|
||||||
value: GaugeValue = None,
|
value: GaugeValue = None,
|
||||||
min_value: float = 0.0,
|
min_value: float = 0.0,
|
||||||
@@ -403,6 +413,7 @@ def status_light(
|
|||||||
def segmented_gauge(
|
def segmented_gauge(
|
||||||
*,
|
*,
|
||||||
tag: Tag | None = None,
|
tag: Tag | None = None,
|
||||||
|
parent: Tag | None = None,
|
||||||
label: str | None = None,
|
label: str | None = None,
|
||||||
value: GaugeValue = None,
|
value: GaugeValue = None,
|
||||||
min_value: float = 0.0,
|
min_value: float = 0.0,
|
||||||
@@ -443,6 +454,7 @@ def segmented_gauge(
|
|||||||
def compass_gauge(
|
def compass_gauge(
|
||||||
*,
|
*,
|
||||||
tag: Tag | None = None,
|
tag: Tag | None = None,
|
||||||
|
parent: Tag | None = None,
|
||||||
label: str | None = None,
|
label: str | None = None,
|
||||||
value: GaugeValue = None,
|
value: GaugeValue = None,
|
||||||
min_value: float = 0.0,
|
min_value: float = 0.0,
|
||||||
@@ -488,6 +500,7 @@ def compass_gauge(
|
|||||||
def thermometer_gauge(
|
def thermometer_gauge(
|
||||||
*,
|
*,
|
||||||
tag: Tag | None = None,
|
tag: Tag | None = None,
|
||||||
|
parent: Tag | None = None,
|
||||||
label: str | None = None,
|
label: str | None = None,
|
||||||
value: GaugeValue = None,
|
value: GaugeValue = None,
|
||||||
min_value: float = 0.0,
|
min_value: float = 0.0,
|
||||||
@@ -529,6 +542,7 @@ def thermometer_gauge(
|
|||||||
def battery_gauge(
|
def battery_gauge(
|
||||||
*,
|
*,
|
||||||
tag: Tag | None = None,
|
tag: Tag | None = None,
|
||||||
|
parent: Tag | None = None,
|
||||||
label: str | None = None,
|
label: str | None = None,
|
||||||
value: GaugeValue = None,
|
value: GaugeValue = None,
|
||||||
min_value: float = 0.0,
|
min_value: float = 0.0,
|
||||||
@@ -569,6 +583,7 @@ def battery_gauge(
|
|||||||
def multi_value_gauge(
|
def multi_value_gauge(
|
||||||
*,
|
*,
|
||||||
tag: Tag | None = None,
|
tag: Tag | None = None,
|
||||||
|
parent: Tag | None = None,
|
||||||
label: str | None = None,
|
label: str | None = None,
|
||||||
value: GaugeValue = None,
|
value: GaugeValue = None,
|
||||||
min_value: float = 0.0,
|
min_value: float = 0.0,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# pyright: reportGeneralTypeIssues=false
|
# pyright: reportGeneralTypeIssues=false
|
||||||
|
|
||||||
from collections.abc import Generator
|
from collections.abc import Generator
|
||||||
|
from importlib.resources import files
|
||||||
|
|
||||||
import dearpygui.dearpygui as dpg
|
import dearpygui.dearpygui as dpg
|
||||||
import pytest
|
import pytest
|
||||||
@@ -30,11 +31,22 @@ def dpg_context() -> Generator[None]:
|
|||||||
|
|
||||||
|
|
||||||
def test_public_exports_and_version() -> None:
|
def test_public_exports_and_version() -> None:
|
||||||
assert dpgg.__version__ == "1.0.0"
|
assert dpgg.__version__ == "1.0.2"
|
||||||
|
assert files("dpg_gauges").joinpath("py.typed").is_file()
|
||||||
for name in dpgg.__all__:
|
for name in dpgg.__all__:
|
||||||
assert hasattr(dpgg, name)
|
assert hasattr(dpgg, name)
|
||||||
|
|
||||||
|
|
||||||
|
def test_gauge_creation_supports_explicit_parent(dpg_context: None) -> None:
|
||||||
|
dpg.add_window(tag="late_parent", label="Late Parent")
|
||||||
|
|
||||||
|
dpgg.analog_gauge(tag="late_gauge", parent="late_parent", width=180, height=180)
|
||||||
|
|
||||||
|
state = get_gauge_state("late_gauge")
|
||||||
|
assert state.config.parent == "late_parent"
|
||||||
|
assert dpg.get_item_parent(state.container_tag) == "late_parent"
|
||||||
|
|
||||||
|
|
||||||
def test_unknown_duplicate_and_deleted_gauge_errors() -> None:
|
def test_unknown_duplicate_and_deleted_gauge_errors() -> None:
|
||||||
with pytest.raises(GaugeNotFoundError):
|
with pytest.raises(GaugeNotFoundError):
|
||||||
dpgg.set_value("missing", 1)
|
dpgg.set_value("missing", 1)
|
||||||
|
|||||||
Reference in New Issue
Block a user