Skip to content

Commit 133ab82

Browse files
committed
items.XRangeSelection is now serializable
1 parent 6d803b0 commit 133ab82

File tree

3 files changed

+53
-2
lines changed

3 files changed

+53
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
* Fixed `plotpy.tools.AnnotatedEllipseTool`: `AttributeError` when finalizing the shape
88
* `plotpy.widgets.select_with_shape_tool`: added missing `toolbar` and `options` parameters
9+
* `items.XRangeSelection` is now serializable, as expected
910

1011
📚 Documentation:
1112

plotpy/io.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,7 @@ def register_serializable_items(modname, classnames):
636636
"MaskedImageItem",
637637
"MaskedXYImageItem",
638638
"Marker",
639+
"XRangeSelection",
639640
"PolygonShape",
640641
"PointShape",
641642
"SegmentShape",

plotpy/items/shape/range.py

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import math
66
from typing import TYPE_CHECKING
77

8+
import guidata.dataset.io
89
import numpy as np
910
from guidata.configtools import get_icon
1011
from guidata.dataset import update_dataset
@@ -35,7 +36,10 @@ class XRangeSelection(AbstractShape):
3536
"""
3637

3738
def __init__(
38-
self, _min: float, _max: float, shapeparam: RangeShapeParam | None = None
39+
self,
40+
_min: float | None = None,
41+
_max: float | None = None,
42+
shapeparam: RangeShapeParam | None = None,
3943
) -> None:
4044
super().__init__()
4145
self._min = _min
@@ -51,9 +55,54 @@ def __init__(
5155
self.handle = None
5256
self.symbol = None
5357
self.sel_symbol = None
54-
self.shapeparam.update_range(self) # creates all the above QObjects
58+
if self._min is not None and self._max is not None:
59+
self.shapeparam.update_range(self) # creates all the above QObjects
5560
self.setIcon(get_icon("xrange.png"))
5661

62+
def __reduce__(self) -> tuple[type, tuple, tuple]:
63+
"""Return state information for pickling"""
64+
self.shapeparam.update_param(self)
65+
state = (self.shapeparam, self._min, self._max)
66+
return (XRangeSelection, (), state)
67+
68+
def __setstate__(self, state: tuple) -> None:
69+
"""Restore state information from pickling"""
70+
self.shapeparam, self._min, self._max = state
71+
self.shapeparam.update_range(self)
72+
73+
def serialize(
74+
self,
75+
writer: guidata.dataset.io.HDF5Writer
76+
| guidata.dataset.io.INIWriter
77+
| guidata.dataset.io.JSONWriter,
78+
) -> None:
79+
"""Serialize object to HDF5 writer
80+
81+
Args:
82+
writer: HDF5, INI or JSON writer
83+
"""
84+
self.shapeparam.update_param(self)
85+
writer.write(self.shapeparam, group_name="shapeparam")
86+
writer.write(self._min, group_name="min")
87+
writer.write(self._max, group_name="max")
88+
89+
def deserialize(
90+
self,
91+
reader: guidata.dataset.io.HDF5Reader
92+
| guidata.dataset.io.INIReader
93+
| guidata.dataset.io.JSONReader,
94+
) -> None:
95+
"""Deserialize object from HDF5 reader
96+
97+
Args:
98+
reader: HDF5, INI or JSON reader
99+
"""
100+
self._min = reader.read("min")
101+
self._max = reader.read("max")
102+
self.shapeparam = RangeShapeParam(_("Range"), icon="xrange.png")
103+
reader.read("shapeparam", instance=self.shapeparam)
104+
self.shapeparam.update_range(self)
105+
57106
def get_handles_pos(self) -> tuple[float, float, float]:
58107
"""Return the handles position
59108

0 commit comments

Comments
 (0)