Skip to content

Commit 0546fcb

Browse files
committed
Icon handling in plot items: use a dedicated icon name attribute
1 parent b12a969 commit 0546fcb

24 files changed

+171
-35
lines changed

CHANGELOG.md

+9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog #
22

3+
## Version 2.7.2 ##
4+
5+
🛠️ Bug fixes:
6+
7+
* Fixed regression with respect to `guiqwt` regarding plot items instantiation:
8+
* `guiqwt` was allowing to instantiate plot items without needing to create a `QApplication` instance (no GUI event loop was required)
9+
* This was not the case with `plotpy`, so that it was not possible -for example- to serialize/deserialize plot items to JSON without creating a `QApplication` instance
10+
* This is now fixed
11+
312
## Version 2.7.1 ##
413

514
🛠️ Bug fixes:

plotpy/interfaces/items.py

+17
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,23 @@ class IBasePlotItem:
249249
_can_move = True
250250
_can_resize = True
251251
_can_rotate = True
252+
_icon_name = "" # Icon name (e.g. "point.png")
253+
254+
def get_icon_name(self) -> str:
255+
"""Return the icon name
256+
257+
Returns:
258+
Icon name
259+
"""
260+
return self._icon_name
261+
262+
def set_icon_name(self, icon_name: str) -> None:
263+
"""Set the icon name
264+
265+
Args:
266+
icon_name: Icon name
267+
"""
268+
self._icon_name = icon_name
252269

253270
def set_selectable(self, state: bool) -> None:
254271
"""Set item selectable state

plotpy/items/annotation.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class AnnotatedShape(AbstractShape):
6060
"""
6161

6262
__implements__ = (IBasePlotItem, ISerializableType)
63+
_icon_name = "annotation.png"
6364
SHAPE_CLASS: type[AbstractShape] = RectangleShape # to be overridden
6465
LABEL_ANCHOR: str = ""
6566

@@ -88,7 +89,6 @@ def info_callback(annotation: AnnotatedShape) -> str:
8889
else:
8990
self.annotationparam = annotationparam
9091
self.annotationparam.update_item(self)
91-
self.setIcon(get_icon("annotation.png"))
9292

9393
def types(self) -> tuple[type[IItemType], ...]:
9494
"""Returns a group or category for this item.
@@ -485,6 +485,7 @@ class AnnotatedPoint(AnnotatedShape):
485485
*annotationparam* (see :py:class:`.styles.AnnotationParam`)
486486
"""
487487

488+
_icon_name = "point_shape.png"
488489
SHAPE_CLASS = PointShape
489490
LABEL_ANCHOR = "TL"
490491

@@ -498,7 +499,6 @@ def __init__(
498499
super().__init__(annotationparam, info_callback)
499500
self.shape: PointShape
500501
self.set_pos(x, y)
501-
self.setIcon(get_icon("point_shape.png"))
502502

503503
# ----Public API-------------------------------------------------------------
504504
def set_pos(self, x, y):
@@ -547,6 +547,7 @@ class AnnotatedSegment(AnnotatedShape):
547547
(see :py:class:`.styles.AnnotationParam`)
548548
"""
549549

550+
_icon_name = "segment.png"
550551
SHAPE_CLASS = SegmentShape
551552
LABEL_ANCHOR = "C"
552553

@@ -562,7 +563,6 @@ def __init__(
562563
super().__init__(annotationparam, info_callback)
563564
self.shape: SegmentShape
564565
self.set_rect(x1, y1, x2, y2)
565-
self.setIcon(get_icon("segment.png"))
566566

567567
# ----Public API-------------------------------------------------------------
568568
def set_rect(self, x1, y1, x2, y2):
@@ -619,6 +619,7 @@ class AnnotatedPolygon(AnnotatedShape):
619619
annotationparam: Annotation parameters
620620
"""
621621

622+
_icon_name = "polygon.png"
622623
SHAPE_CLASS = PolygonShape
623624
LABEL_ANCHOR = "C"
624625

@@ -635,7 +636,6 @@ def __init__(
635636
self.set_points(points)
636637
if closed is not None:
637638
self.set_closed(closed)
638-
self.setIcon(get_icon("polygon.png"))
639639

640640
# ----Public API-------------------------------------------------------------
641641
def set_points(self, points: list[tuple[float, float]] | np.ndarray | None) -> None:
@@ -775,6 +775,7 @@ class AnnotatedRectangle(AnnotatedShape):
775775
(see :py:class:`.styles.AnnotationParam`)
776776
"""
777777

778+
_icon_name = "rectangle.png"
778779
SHAPE_CLASS = RectangleShape
779780
LABEL_ANCHOR = "TL"
780781

@@ -790,7 +791,6 @@ def __init__(
790791
super().__init__(annotationparam, info_callback)
791792
self.shape: RectangleShape
792793
self.set_rect(x1, y1, x2, y2)
793-
self.setIcon(get_icon("rectangle.png"))
794794

795795
# ----Public API-------------------------------------------------------------
796796
def set_rect(self, x1, y1, x2, y2):
@@ -842,6 +842,7 @@ class AnnotatedObliqueRectangle(AnnotatedRectangle):
842842
(see :py:class:`.styles.AnnotationParam`)
843843
"""
844844

845+
_icon_name = "oblique_rectangle.png"
845846
SHAPE_CLASS = ObliqueRectangleShape
846847
LABEL_ANCHOR = "C"
847848

@@ -851,7 +852,6 @@ def __init__(
851852
AnnotatedShape.__init__(self, annotationparam)
852853
self.shape: ObliqueRectangleShape
853854
self.set_rect(x0, y0, x1, y1, x2, y2, x3, y3)
854-
self.setIcon(get_icon("oblique_rectangle.png"))
855855

856856
# ----Public API-------------------------------------------------------------
857857
def get_tr_angle(self):
@@ -940,6 +940,7 @@ class AnnotatedEllipse(AnnotatedShape):
940940
(see :py:class:`.styles.AnnotationParam`)
941941
"""
942942

943+
_icon_name = "ellipse_shape.png"
943944
SHAPE_CLASS = EllipseShape
944945
LABEL_ANCHOR = "C"
945946

@@ -955,7 +956,6 @@ def __init__(
955956
super().__init__(annotationparam, info_callback)
956957
self.shape: EllipseShape
957958
self.set_xdiameter(x1, y1, x2, y2)
958-
self.setIcon(get_icon("ellipse_shape.png"))
959959
self.switch_to_ellipse()
960960

961961
# ----Public API-------------------------------------------------------------

plotpy/items/contour.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,10 @@ class ContourItem(PolygonShape):
110110
_can_resize = False
111111
_can_rotate = False
112112
_can_move = False
113+
_icon_name = "contour.png"
113114

114115
def __init__(self, points=None, shapeparam=None):
115116
super().__init__(points, closed=True, shapeparam=shapeparam)
116-
self.setIcon(get_icon("contour.png"))
117117

118118

119119
assert_interfaces_valid(ContourItem)

plotpy/items/curve/base.py

+17-1
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ class CurveItem(QwtPlotCurve):
111111

112112
_readonly = False
113113
_private = False
114+
_icon_name = "curve.png"
114115

115116
def __init__(self, curveparam: CurveParam | None = None) -> None:
116117
super().__init__()
@@ -123,7 +124,6 @@ def __init__(self, curveparam: CurveParam | None = None) -> None:
123124
self._x = None
124125
self._y = None
125126
self.update_params()
126-
self.setIcon(get_icon("curve.png"))
127127

128128
def _get_visible_axis_min(self, axis_id: int, axis_data: np.ndarray) -> float:
129129
"""Return axis minimum excluding zero and negative values when
@@ -172,6 +172,22 @@ def types(self) -> tuple[type[IItemType], ...]:
172172
"""
173173
return (ICurveItemType, ITrackableItemType, ISerializableType)
174174

175+
def get_icon_name(self) -> str:
176+
"""Return the icon name
177+
178+
Returns:
179+
Icon name
180+
"""
181+
return self._icon_name
182+
183+
def set_icon_name(self, icon_name: str) -> None:
184+
"""Set the icon name
185+
186+
Args:
187+
icon_name: Icon name
188+
"""
189+
self._icon_name = icon_name
190+
175191
def set_selectable(self, state: bool) -> None:
176192
"""Set item selectable state
177193

plotpy/items/curve/errorbar.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ class ErrorBarCurveItem(CurveItem):
5656
errorbarparam: Error-bar parameters
5757
"""
5858

59+
_icon_name = "errorbar.png"
60+
5961
def __init__(
6062
self,
6163
curveparam: CurveParam | None = None,
@@ -73,7 +75,6 @@ def __init__(
7375
self._dx = None
7476
self._dy = None
7577
self.__minmaxarrays: dict[bool, tuple[float, float, float, float]] = {}
76-
self.setIcon(get_icon("errorbar.png"))
7778

7879
def serialize(
7980
self,

plotpy/items/grid.py

+17-1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class GridItem(QwtPlotGrid):
3636

3737
_readonly = True
3838
_private = False
39+
_icon_name = "grid.png"
3940

4041
def __init__(self, gridparam: GridParam | None = None) -> None:
4142
super().__init__()
@@ -47,7 +48,6 @@ def __init__(self, gridparam: GridParam | None = None) -> None:
4748
self.immutable = True # set to false to allow moving points around
4849
self.update_params() # won't work completely because it's not yet
4950
# attached to plot (actually, only canvas background won't be updated)
50-
self.setIcon(get_icon("grid.png"))
5151

5252
def types(self) -> tuple[type[IItemType], ...]:
5353
"""Returns a group or category for this item.
@@ -95,6 +95,22 @@ def is_private(self) -> bool:
9595
"""
9696
return self._private
9797

98+
def get_icon_name(self) -> str:
99+
"""Return the icon name
100+
101+
Returns:
102+
Icon name
103+
"""
104+
return self._icon_name
105+
106+
def set_icon_name(self, icon_name: str) -> None:
107+
"""Set the icon name
108+
109+
Args:
110+
icon_name: Icon name
111+
"""
112+
self._icon_name = icon_name
113+
98114
def set_selectable(self, state: bool) -> None:
99115
"""Set item selectable state
100116

plotpy/items/histogram.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class HistogramItem(CurveItem):
6767
"""
6868

6969
__implements__ = (IBasePlotItem,)
70+
_icon_name = "histogram.png"
7071

7172
def __init__(
7273
self,
@@ -92,7 +93,6 @@ def __init__(
9293
self.histparam = histparam
9394
CurveItem.__init__(self, curveparam)
9495
self.setCurveAttribute(QwtPlotCurve.Inverted)
95-
self.setIcon(get_icon("histogram.png"))
9696

9797
def set_hist_source(self, src: BaseImageItem) -> None:
9898
"""Set histogram source

plotpy/items/image/base.py

+17-1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class BaseImageItem(QwtPlotItem):
8282
_can_rotate = False
8383
_readonly = False
8484
_private = False
85+
_icon_name = "image.png"
8586

8687
def __init__(
8788
self, data: np.ndarray | None = None, param: Any | None = None
@@ -134,7 +135,6 @@ def __init__(
134135
if data is not None:
135136
self.set_data(data)
136137
self.param.update_item(self)
137-
self.setIcon(get_icon("image.png"))
138138

139139
# ---- Public API ----------------------------------------------------------
140140
def get_default_param(self) -> Any:
@@ -777,6 +777,22 @@ def is_empty(self) -> bool:
777777
"""
778778
return self.data is None or self.data.size == 0
779779

780+
def get_icon_name(self) -> str:
781+
"""Return the icon name
782+
783+
Returns:
784+
Icon name
785+
"""
786+
return self._icon_name
787+
788+
def set_icon_name(self, icon_name: str) -> None:
789+
"""Set the icon name
790+
791+
Args:
792+
icon_name: Icon name
793+
"""
794+
self._icon_name = icon_name
795+
780796
def set_selectable(self, state: bool) -> None:
781797
"""Set item selectable state
782798

plotpy/items/image/filter.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ class ImageFilterItem(BaseImageItem):
7575
_can_select = True
7676
_can_resize = True
7777
_can_move = True
78+
_icon_name = "funct.png"
7879

7980
def __init__(
8081
self, image: RawImageItem | None, filter: Callable, param: ImageFilterParam
@@ -92,7 +93,6 @@ def __init__(
9293

9394
self.imagefilterparam = param
9495
self.imagefilterparam.update_imagefilter(self)
95-
self.setIcon(get_icon("funct.png"))
9696

9797
# ---- Public API -----------------------------------------------------------
9898
def set_image(self, image: RawImageItem | None) -> None:

plotpy/items/image/misc.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ class Histogram2DItem(BaseImageItem):
206206
"""
207207

208208
__implements__ = (IBasePlotItem, IBaseImageItem, IHistDataSource, IVoiImageItemType)
209+
_icon_name = "histogram2d.png"
209210

210211
def __init__(
211212
self,
@@ -234,7 +235,6 @@ def __init__(
234235

235236
self.set_lut_range([0, 10.0])
236237
self.set_data(X, Y, Z)
237-
self.setIcon(get_icon("histogram2d.png"))
238238

239239
# ---- BaseImageItem API ---------------------------------------------------
240240
def get_default_param(self) -> Histogram2DParam:

plotpy/items/label.py

+18-2
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,22 @@ def get_origin(
207207
y0 = yMap.transform(self.G[1])
208208
return x0, y0
209209

210+
def get_icon_name(self) -> str:
211+
"""Return the icon name
212+
213+
Returns:
214+
Icon name
215+
"""
216+
return self._icon_name
217+
218+
def set_icon_name(self, icon_name: str) -> None:
219+
"""Set the icon name
220+
221+
Args:
222+
icon_name: Icon name
223+
"""
224+
self._icon_name = icon_name
225+
210226
def set_selectable(self, state: bool) -> None:
211227
"""Set item selectable state
212228
@@ -497,6 +513,7 @@ class LabelItem(AbstractLabelItem):
497513
"""
498514

499515
__implements__ = (IBasePlotItem, ISerializableType)
516+
_icon_name = "label.png"
500517

501518
def __init__(
502519
self, text: str | None = None, labelparam: LabelParam | None = None
@@ -505,7 +522,6 @@ def __init__(
505522
self.text = QG.QTextDocument()
506523
self.marker: qwt.symbol.QwtSymbol | None = None
507524
super().__init__(labelparam)
508-
self.setIcon(get_icon("label.png"))
509525

510526
def __reduce__(self) -> tuple[type, tuple]:
511527
"""Return a tuple containing the constructor and its arguments"""
@@ -645,14 +661,14 @@ class LegendBoxItem(AbstractLabelItem):
645661
"""
646662

647663
__implements__ = (IBasePlotItem, ISerializableType)
664+
_icon_name = "legend.png"
648665

649666
def __init__(self, labelparam: LabelParam = None) -> None:
650667
self.font = None
651668
self.color = None
652669
super().__init__(labelparam)
653670
# saves the last computed sizes
654671
self.sizes = 0.0, 0.0, 0.0, 0.0
655-
self.setIcon(get_icon("legend.png"))
656672

657673
def types(self) -> tuple[type[IItemType], ...]:
658674
"""Returns a group or category for this item.

0 commit comments

Comments
 (0)