QT-PyQt-PySide-Custom-Widgets-Pro 1.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. custom_widgets_pro/__init__.py +73 -0
  2. custom_widgets_pro/_catalog.py +25 -0
  3. custom_widgets_pro/_cli.py +132 -0
  4. custom_widgets_pro/_license.py +419 -0
  5. custom_widgets_pro/_version.py +14 -0
  6. custom_widgets_pro/datatable/__init__.py +17 -0
  7. custom_widgets_pro/datatable/datatable_pro.py +319 -0
  8. custom_widgets_pro/datatable/export.py +143 -0
  9. custom_widgets_pro/datatable/frozen_view.py +112 -0
  10. custom_widgets_pro/datatable/grouping.py +309 -0
  11. custom_widgets_pro/datatable/pivot.py +100 -0
  12. custom_widgets_pro/datatable/provider.py +98 -0
  13. custom_widgets_pro/datatable/virtual_model.py +451 -0
  14. custom_widgets_pro/widgets/__init__.py +7 -0
  15. custom_widgets_pro/widgets/charts/QCustomBeeswarm.py +317 -0
  16. custom_widgets_pro/widgets/charts/QCustomBubbleChart.py +655 -0
  17. custom_widgets_pro/widgets/charts/QCustomCandlestickChart.py +522 -0
  18. custom_widgets_pro/widgets/charts/QCustomDivergingBarChart.py +430 -0
  19. custom_widgets_pro/widgets/charts/QCustomDotMatrix.py +266 -0
  20. custom_widgets_pro/widgets/charts/QCustomFunnelChart.py +474 -0
  21. custom_widgets_pro/widgets/charts/QCustomGanttChart.py +376 -0
  22. custom_widgets_pro/widgets/charts/QCustomHeatmap.py +555 -0
  23. custom_widgets_pro/widgets/charts/QCustomRadarChart.py +600 -0
  24. custom_widgets_pro/widgets/charts/QCustomRadialBars.py +441 -0
  25. custom_widgets_pro/widgets/charts/QCustomRadialLines.py +554 -0
  26. custom_widgets_pro/widgets/charts/QCustomRangeBarChart.py +504 -0
  27. custom_widgets_pro/widgets/charts/QCustomSankey.py +539 -0
  28. custom_widgets_pro/widgets/charts/QCustomScatterChart.py +623 -0
  29. custom_widgets_pro/widgets/charts/__init__.py +1 -0
  30. custom_widgets_pro/widgets/data/QCustomCodeEditor.py +391 -0
  31. custom_widgets_pro/widgets/data/QCustomNodeGraph.py +1030 -0
  32. custom_widgets_pro/widgets/data/QCustomRichTextEditor.py +189 -0
  33. custom_widgets_pro/widgets/data/QCustomTableToolbar.py +566 -0
  34. custom_widgets_pro/widgets/data/__init__.py +1 -0
  35. custom_widgets_pro/widgets/media/QCustomImageViewer.py +300 -0
  36. custom_widgets_pro/widgets/media/QCustomMediaGrid.py +197 -0
  37. custom_widgets_pro/widgets/media/QCustomMediaTimeline.py +607 -0
  38. custom_widgets_pro/widgets/media/QCustomVideoPlayer.py +326 -0
  39. custom_widgets_pro/widgets/media/__init__.py +1 -0
  40. qt_pyqt_pyside_custom_widgets_pro-1.1.0.dist-info/METADATA +112 -0
  41. qt_pyqt_pyside_custom_widgets_pro-1.1.0.dist-info/RECORD +45 -0
  42. qt_pyqt_pyside_custom_widgets_pro-1.1.0.dist-info/WHEEL +5 -0
  43. qt_pyqt_pyside_custom_widgets_pro-1.1.0.dist-info/entry_points.txt +2 -0
  44. qt_pyqt_pyside_custom_widgets_pro-1.1.0.dist-info/licenses/LICENSE +91 -0
  45. qt_pyqt_pyside_custom_widgets_pro-1.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,554 @@
1
+ ########################################################################
2
+ ## SPINN DESIGN CODE
3
+ # YOUTUBE: (SPINN TV) https://www.youtube.com/@SpinnTV
4
+ # WEBSITE: customwidgets.org
5
+ ########################################################################
6
+
7
+ ########################################################################
8
+ ## QCustomRadialLines - a painted polar line chart.
9
+ ##
10
+ ## A line chart wrapped onto a circle: the x axis is angular, so the series
11
+ ## closes back on itself. The right form for cyclical data - hours of a day,
12
+ ## months of a year, compass bearings - where a cartesian line chart puts an
13
+ ## artificial break between the last point and the first.
14
+ ##
15
+ ## Distinct from QCustomRadarChart: radar compares a handful of NAMED axes as
16
+ ## a shape; this plots a continuous series around a circle and does not label
17
+ ## every sample.
18
+ ##
19
+ ## QPainter only, NO QtCharts (see docs/design/mui-charts-gap.md). Angles come
20
+ ## from the shared _chart_axis polar helpers so it winds the same way as the
21
+ ## other radial charts.
22
+ ##
23
+ ## Data goes in with addSeries(name, values) in code, or seriesCsv in Qt
24
+ ## Designer:
25
+ ##
26
+ ## seriesCsv = "Weekday=30,45,60,52,48,70,64;Weekend=20,25,40,38,30,35,28"
27
+ ##
28
+ ## Emits seriesHovered(int) and pointClicked(int, int); -1 means "nothing".
29
+ ########################################################################
30
+ import math
31
+
32
+ from qtpy.QtCore import Qt, Signal, Property, QRectF, QSize, QPointF
33
+ from qtpy.QtGui import QColor, QPainter, QPen, QBrush, QPolygonF, QFontMetrics
34
+ from qtpy.QtWidgets import QWidget, QSizePolicy
35
+
36
+ # _chart_axis stays in the free package; Pro depends on it, so import
37
+ # it absolutely rather than duplicating the helper here.
38
+ from Custom_Widgets.widgets.charts._chart_axis import polarAngle, polarPoint
39
+
40
+
41
+ class QCustomRadialLines(QWidget):
42
+ seriesHovered = Signal(int)
43
+ pointClicked = Signal(int, int)
44
+
45
+ WIDGET_ICON = "components/icons/track_changes.png"
46
+ WIDGET_TOOLTIP = "A painted polar line chart for cyclical data"
47
+ WIDGET_MODULE = "Custom_Widgets.QCustomRadialLines"
48
+ WIDGET_DOM_XML = """
49
+ <ui language='c++'>
50
+ <widget class='QCustomRadialLines' name='customRadialLines'>
51
+ <property name='geometry'><rect><x>0</x><y>0</y><width>300</width><height>300</height></rect></property>
52
+ <property name='seriesCsv'><string>Weekday=30,45,60,52,48,70,64</string></property>
53
+ </widget>
54
+ </ui>
55
+ """
56
+ __catalog__ = {
57
+ "name": "QCustomRadialLines",
58
+ "props": {"seriesCsv": {"type": "string", "default": ""},
59
+ "labelsCsv": {"type": "string", "default": ""},
60
+ "colorsCsv": {"type": "string", "default": ""},
61
+ "maxValue": {"type": "float", "default": 0.0},
62
+ "startAngle": {"type": "int", "default": 90},
63
+ "clockwise": {"type": "bool", "default": True},
64
+ "rings": {"type": "int", "default": 4},
65
+ "lineWidth": {"type": "float", "default": 2.0},
66
+ "fillOpacity": {"type": "float", "default": 0.15},
67
+ "closed": {"type": "bool", "default": True},
68
+ "smooth": {"type": "bool", "default": False},
69
+ "showGrid": {"type": "bool", "default": True},
70
+ "showMarkers": {"type": "bool", "default": False},
71
+ "showLabels": {"type": "bool", "default": True},
72
+ "showLegend": {"type": "bool", "default": True},
73
+ "gridColor": {"type": "color", "default": "#e2e8f0"},
74
+ "labelColor": {"type": "color", "default": "#64748b"}},
75
+ "signals": ["seriesHovered", "pointClicked"],
76
+ "tokens_used": ["surface-muted", "on-surface"],
77
+ }
78
+
79
+ # Rich editors for the Designer "Custom Properties" dock (see
80
+ # DesignerTools.CustomPropertiesDock).
81
+ DESIGNER_CUSTOM_PROPS = [
82
+ {"name": "seriesCsv", "kind": "str", "group": "General"},
83
+ {"name": "labelsCsv", "kind": "str", "group": "General"},
84
+ {"name": "colorsCsv", "kind": "str", "group": "Colors"},
85
+ {"name": "maxValue", "kind": "float", "group": "General"},
86
+ {"name": "startAngle", "kind": "int", "group": "General"},
87
+ {"name": "clockwise", "kind": "bool", "group": "General"},
88
+ {"name": "rings", "kind": "int", "group": "General"},
89
+ {"name": "lineWidth", "kind": "float", "group": "General"},
90
+ {"name": "fillOpacity", "kind": "float", "group": "General"},
91
+ {"name": "closed", "kind": "bool", "group": "General"},
92
+ {"name": "smooth", "kind": "bool", "group": "General"},
93
+ {"name": "showGrid", "kind": "bool", "group": "General"},
94
+ {"name": "showMarkers", "kind": "bool", "group": "General"},
95
+ {"name": "showLabels", "kind": "bool", "group": "General"},
96
+ {"name": "showLegend", "kind": "bool", "group": "General"},
97
+ {"name": "gridColor", "kind": "color", "group": "Colors"},
98
+ {"name": "labelColor", "kind": "color", "group": "Colors"},
99
+ ]
100
+
101
+ _DEFAULT_COLORS = ["#2563eb", "#16a34a", "#f59e0b", "#dc2626", "#7c3aed",
102
+ "#0891b2"]
103
+
104
+ def __init__(self, parent=None, series=None, labels=None):
105
+ super().__init__(parent)
106
+ self.setObjectName("QCustomRadialLines")
107
+ self._series = [] # list of (name, [values])
108
+ self._labels = []
109
+ self._colors = []
110
+ self._maxValue = 0.0
111
+ self._startAngle = 90
112
+ self._clockwise = True
113
+ self._rings = 4
114
+ self._lineWidth = 2.0
115
+ self._fillOpacity = 0.15
116
+ self._closed = True
117
+ self._smooth = False
118
+ self._showGrid = True
119
+ self._showMarkers = False
120
+ self._showLabels = True
121
+ self._showLegend = True
122
+ self._hover = -1
123
+
124
+ self._gridColor = QColor("#e2e8f0")
125
+ self._labelColor = QColor("#64748b")
126
+
127
+ self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
128
+ self.setMouseTracking(True)
129
+ if labels:
130
+ self._labels = [str(x) for x in labels]
131
+ for name, values in (series or []):
132
+ self.addSeries(name, values)
133
+
134
+ # ------------------------------------------------------------------ #
135
+ ## Data
136
+ # ------------------------------------------------------------------ #
137
+ def addSeries(self, name, values, color=None):
138
+ cleaned = []
139
+ for value in values or []:
140
+ try:
141
+ cleaned.append(float(value))
142
+ except (TypeError, ValueError):
143
+ continue
144
+ self._series.append((str(name), cleaned))
145
+ if color is not None:
146
+ while len(self._colors) < len(self._series) - 1:
147
+ self._colors.append(None)
148
+ self._colors.append(QColor(color))
149
+ self.update()
150
+ return len(self._series) - 1
151
+
152
+ def setSeries(self, series):
153
+ self._series = []
154
+ for item in series or []:
155
+ if isinstance(item, dict):
156
+ self.addSeries(item.get("name", ""), item.get("values", []))
157
+ elif isinstance(item, (tuple, list)) and len(item) >= 2:
158
+ self.addSeries(item[0], item[1])
159
+ self.update()
160
+
161
+ def series(self):
162
+ return [(name, list(values)) for name, values in self._series]
163
+
164
+ def seriesCount(self):
165
+ return len(self._series)
166
+
167
+ def clearSeries(self):
168
+ self._series = []
169
+ self._colors = []
170
+ self._hover = -1
171
+ self.update()
172
+
173
+ def setLabels(self, labels):
174
+ self._labels = [str(x) for x in (labels or [])]
175
+ self.update()
176
+
177
+ def labels(self):
178
+ return list(self._labels)
179
+
180
+ def sampleCount(self):
181
+ """Samples around the circle — the longest series wins."""
182
+ return max((len(v) for _n, v in self._series), default=0)
183
+
184
+ def seriesColor(self, index):
185
+ if 0 <= index < len(self._colors) and self._colors[index] is not None:
186
+ return QColor(self._colors[index])
187
+ return QColor(self._DEFAULT_COLORS[index % len(self._DEFAULT_COLORS)])
188
+
189
+ def maximum(self):
190
+ if self._maxValue > 0:
191
+ return self._maxValue
192
+ peak = max((v for _n, values in self._series for v in values), default=0.0)
193
+ return peak or 1.0
194
+
195
+ # ------------------------------------------------------------------ #
196
+ ## Geometry
197
+ # ------------------------------------------------------------------ #
198
+ def sizeHint(self):
199
+ return QSize(300, 300)
200
+
201
+ def minimumSizeHint(self):
202
+ return QSize(110, 110)
203
+
204
+ def _legendHeight(self):
205
+ if not (self._showLegend and self._series):
206
+ return 0.0
207
+ return QFontMetrics(self.font()).height() + 8
208
+
209
+ def _plotRect(self):
210
+ pad = 10.0
211
+ if self._showLabels and self._labels:
212
+ pad += QFontMetrics(self.font()).height() + 4
213
+ bottom = self._legendHeight()
214
+ side = max(10.0, min(self.width() - 2 * pad,
215
+ self.height() - 2 * pad - bottom))
216
+ return QRectF((self.width() - side) / 2.0,
217
+ (self.height() - bottom - side) / 2.0, side, side)
218
+
219
+ def _angleFor(self, index):
220
+ return polarAngle(index, max(1, self.sampleCount()),
221
+ self._startAngle, self._clockwise)
222
+
223
+ def pointFor(self, seriesIndex, sampleIndex):
224
+ """Widget-space point for one sample of one series."""
225
+ rect = self._plotRect()
226
+ values = self._series[seriesIndex][1]
227
+ if not values:
228
+ return QPointF(rect.center())
229
+ value = values[sampleIndex % len(values)]
230
+ radius = rect.width() / 2.0 * max(0.0, min(1.0, value / self.maximum()))
231
+ x, y = polarPoint(rect.center().x(), rect.center().y(), radius,
232
+ self._angleFor(sampleIndex))
233
+ return QPointF(x, y)
234
+
235
+ def _polygonFor(self, seriesIndex):
236
+ values = self._series[seriesIndex][1]
237
+ return QPolygonF([self.pointFor(seriesIndex, i)
238
+ for i in range(len(values))])
239
+
240
+ # ------------------------------------------------------------------ #
241
+ ## Painting
242
+ # ------------------------------------------------------------------ #
243
+ def paintEvent(self, e):
244
+ p = QPainter(self)
245
+ p.setRenderHint(QPainter.Antialiasing)
246
+ p.setFont(self.font())
247
+ if not self._series or not self.sampleCount():
248
+ return
249
+
250
+ if self._showGrid:
251
+ self._paintGrid(p)
252
+ for index in range(len(self._series)):
253
+ self._paintSeries(p, index)
254
+ if self._showLabels and self._labels:
255
+ self._paintLabels(p)
256
+ if self._showLegend:
257
+ self._paintLegend(p)
258
+
259
+ def _paintGrid(self, p):
260
+ rect = self._plotRect()
261
+ p.setBrush(Qt.NoBrush)
262
+ p.setPen(QPen(self._gridColor, 1))
263
+ for ring in range(1, max(1, self._rings) + 1):
264
+ radius = rect.width() / 2.0 * ring / float(max(1, self._rings))
265
+ p.drawEllipse(rect.center(), radius, radius)
266
+ # spokes only where a label exists, so a 60-sample series does not
267
+ # bury the data under 60 grid lines
268
+ count = len(self._labels) if self._labels else min(self.sampleCount(), 12)
269
+ for i in range(count):
270
+ step = max(1, self.sampleCount() // max(1, count))
271
+ angle = self._angleFor(i * step)
272
+ x, y = polarPoint(rect.center().x(), rect.center().y(),
273
+ rect.width() / 2.0, angle)
274
+ p.drawLine(rect.center(), QPointF(x, y))
275
+
276
+ def _paintSeries(self, p, index):
277
+ colour = self.seriesColor(index)
278
+ hovered = index == self._hover
279
+ poly = self._polygonFor(index)
280
+ if poly.count() < 2:
281
+ return
282
+
283
+ if self._fillOpacity > 0 and self._closed:
284
+ fill = QColor(colour)
285
+ fill.setAlphaF(max(0.0, min(1.0, self._fillOpacity *
286
+ (1.8 if hovered else 1.0))))
287
+ p.setPen(Qt.NoPen)
288
+ p.setBrush(QBrush(fill))
289
+ p.drawPolygon(poly)
290
+
291
+ p.setBrush(Qt.NoBrush)
292
+ p.setPen(QPen(colour, self._lineWidth + (1.0 if hovered else 0.0)))
293
+ if self._closed:
294
+ p.drawPolygon(poly)
295
+ else:
296
+ p.drawPolyline(poly)
297
+
298
+ if self._showMarkers:
299
+ p.setPen(Qt.NoPen)
300
+ p.setBrush(QBrush(colour))
301
+ radius = 3.0 + (1.0 if hovered else 0.0)
302
+ for point in poly:
303
+ p.drawEllipse(point, radius, radius)
304
+
305
+ def _paintLabels(self, p):
306
+ rect = self._plotRect()
307
+ fm = QFontMetrics(self.font())
308
+ p.setPen(QPen(self._labelColor))
309
+ count = self.sampleCount()
310
+ for i, label in enumerate(self._labels[:count]):
311
+ step = max(1, count // max(1, len(self._labels)))
312
+ angle = self._angleFor(i * step)
313
+ x, y = polarPoint(rect.center().x(), rect.center().y(),
314
+ rect.width() / 2.0 + 6, angle)
315
+ width = fm.horizontalAdvance(label)
316
+ if x < rect.center().x() - 1:
317
+ x -= width
318
+ elif abs(x - rect.center().x()) <= 1:
319
+ x -= width / 2.0
320
+ p.drawText(QRectF(x, y - fm.height() / 2.0, width, fm.height()),
321
+ int(Qt.AlignCenter), label)
322
+
323
+ def _paintLegend(self, p):
324
+ fm = QFontMetrics(self.font())
325
+ swatch, gap = 9.0, 14.0
326
+ widths = [swatch + 5 + fm.horizontalAdvance(name)
327
+ for name, _v in self._series]
328
+ x = (self.width() - (sum(widths) + gap * (len(widths) - 1))) / 2.0
329
+ y = self.height() - self._legendHeight() + 2
330
+ for index, (name, _values) in enumerate(self._series):
331
+ p.setPen(Qt.NoPen)
332
+ p.setBrush(QBrush(self.seriesColor(index)))
333
+ p.drawEllipse(QRectF(x, y + (fm.height() - swatch) / 2.0,
334
+ swatch, swatch))
335
+ p.setPen(QPen(self._labelColor))
336
+ p.drawText(QRectF(x + swatch + 5, y, widths[index], fm.height()),
337
+ int(Qt.AlignLeft | Qt.AlignVCenter), name)
338
+ x += widths[index] + gap
339
+
340
+ # ------------------------------------------------------------------ #
341
+ ## Interaction
342
+ # ------------------------------------------------------------------ #
343
+ def sampleAt(self, pos):
344
+ """(series, sample) nearest a point, or (-1, -1)."""
345
+ point = QPointF(pos)
346
+ best, bestDistance = (-1, -1), None
347
+ for si in range(len(self._series) - 1, -1, -1):
348
+ for i in range(len(self._series[si][1])):
349
+ mapped = self.pointFor(si, i)
350
+ distance = math.hypot(point.x() - mapped.x(),
351
+ point.y() - mapped.y())
352
+ if distance <= 10.0 and (bestDistance is None or distance < bestDistance):
353
+ best, bestDistance = (si, i), distance
354
+ return best
355
+
356
+ def seriesAt(self, pos):
357
+ """Index of the series whose closed shape contains a point, else -1."""
358
+ point = QPointF(pos)
359
+ for index in range(len(self._series) - 1, -1, -1):
360
+ poly = self._polygonFor(index)
361
+ if poly.count() >= 3 and poly.containsPoint(point, Qt.OddEvenFill):
362
+ return index
363
+ return -1
364
+
365
+ def mouseMoveEvent(self, e):
366
+ index = self.seriesAt(e.pos())
367
+ if index != self._hover:
368
+ self._hover = index
369
+ self.seriesHovered.emit(index)
370
+ self.update()
371
+ super().mouseMoveEvent(e)
372
+
373
+ def leaveEvent(self, e):
374
+ if self._hover != -1:
375
+ self._hover = -1
376
+ self.seriesHovered.emit(-1)
377
+ self.update()
378
+ super().leaveEvent(e)
379
+
380
+ def mouseReleaseEvent(self, e):
381
+ if e.button() == Qt.LeftButton:
382
+ si, i = self.sampleAt(e.pos())
383
+ if si >= 0:
384
+ self.pointClicked.emit(si, i)
385
+ super().mouseReleaseEvent(e)
386
+
387
+ # ------------------------------------------------------------------ #
388
+ ## Designer properties
389
+ # ------------------------------------------------------------------ #
390
+ @Property(str)
391
+ def seriesCsv(self):
392
+ return ";".join("%s=%s" % (name, ",".join("%g" % v for v in values))
393
+ for name, values in self._series)
394
+
395
+ @seriesCsv.setter
396
+ def seriesCsv(self, text):
397
+ parsed = []
398
+ for chunk in str(text).replace("|", ";").split(";"):
399
+ chunk = chunk.strip()
400
+ if not chunk:
401
+ continue
402
+ if "=" in chunk:
403
+ name, _, raw = chunk.partition("=")
404
+ name = name.strip() or "Series %d" % (len(parsed) + 1)
405
+ else:
406
+ name, raw = "Series %d" % (len(parsed) + 1), chunk
407
+ values = []
408
+ for token in raw.split(","):
409
+ token = token.strip()
410
+ if not token:
411
+ continue
412
+ try:
413
+ values.append(float(token))
414
+ except ValueError:
415
+ pass
416
+ if values:
417
+ parsed.append((name, values))
418
+ self.setSeries(parsed)
419
+
420
+ @Property(str)
421
+ def labelsCsv(self):
422
+ return ",".join(self._labels)
423
+
424
+ @labelsCsv.setter
425
+ def labelsCsv(self, text):
426
+ self.setLabels([t.strip() for t in str(text).replace(";", ",").split(",")
427
+ if t.strip()])
428
+
429
+ @Property(str)
430
+ def colorsCsv(self):
431
+ return ",".join(c.name() if c is not None else "" for c in self._colors)
432
+
433
+ @colorsCsv.setter
434
+ def colorsCsv(self, text):
435
+ colors = []
436
+ for token in str(text).replace(";", ",").split(","):
437
+ token = token.strip()
438
+ colour = QColor(token) if token else QColor()
439
+ colors.append(colour if colour.isValid() else None)
440
+ self._colors = colors
441
+ self.update()
442
+
443
+ @Property(float)
444
+ def maxValue(self):
445
+ return self._maxValue
446
+
447
+ @maxValue.setter
448
+ def maxValue(self, value):
449
+ self._maxValue = max(0.0, float(value)); self.update()
450
+
451
+ @Property(int)
452
+ def startAngle(self):
453
+ return self._startAngle
454
+
455
+ @startAngle.setter
456
+ def startAngle(self, value):
457
+ self._startAngle = int(value) % 360; self.update()
458
+
459
+ @Property(bool)
460
+ def clockwise(self):
461
+ return self._clockwise
462
+
463
+ @clockwise.setter
464
+ def clockwise(self, value):
465
+ self._clockwise = bool(value); self.update()
466
+
467
+ @Property(int)
468
+ def rings(self):
469
+ return self._rings
470
+
471
+ @rings.setter
472
+ def rings(self, value):
473
+ self._rings = max(1, int(value)); self.update()
474
+
475
+ @Property(float)
476
+ def lineWidth(self):
477
+ return self._lineWidth
478
+
479
+ @lineWidth.setter
480
+ def lineWidth(self, value):
481
+ self._lineWidth = max(0.0, float(value)); self.update()
482
+
483
+ @Property(float)
484
+ def fillOpacity(self):
485
+ return self._fillOpacity
486
+
487
+ @fillOpacity.setter
488
+ def fillOpacity(self, value):
489
+ self._fillOpacity = max(0.0, min(1.0, float(value))); self.update()
490
+
491
+ @Property(bool)
492
+ def closed(self):
493
+ return self._closed
494
+
495
+ @closed.setter
496
+ def closed(self, value):
497
+ self._closed = bool(value); self.update()
498
+
499
+ @Property(bool)
500
+ def smooth(self):
501
+ return self._smooth
502
+
503
+ @smooth.setter
504
+ def smooth(self, value):
505
+ self._smooth = bool(value); self.update()
506
+
507
+ @Property(bool)
508
+ def showGrid(self):
509
+ return self._showGrid
510
+
511
+ @showGrid.setter
512
+ def showGrid(self, value):
513
+ self._showGrid = bool(value); self.update()
514
+
515
+ @Property(bool)
516
+ def showMarkers(self):
517
+ return self._showMarkers
518
+
519
+ @showMarkers.setter
520
+ def showMarkers(self, value):
521
+ self._showMarkers = bool(value); self.update()
522
+
523
+ @Property(bool)
524
+ def showLabels(self):
525
+ return self._showLabels
526
+
527
+ @showLabels.setter
528
+ def showLabels(self, value):
529
+ self._showLabels = bool(value); self.updateGeometry(); self.update()
530
+
531
+ @Property(bool)
532
+ def showLegend(self):
533
+ return self._showLegend
534
+
535
+ @showLegend.setter
536
+ def showLegend(self, value):
537
+ self._showLegend = bool(value); self.updateGeometry(); self.update()
538
+
539
+ # -- colours (from tokens via qproperty) --
540
+ @Property(QColor)
541
+ def gridColor(self):
542
+ return self._gridColor
543
+
544
+ @gridColor.setter
545
+ def gridColor(self, c):
546
+ self._gridColor = QColor(c); self.update()
547
+
548
+ @Property(QColor)
549
+ def labelColor(self):
550
+ return self._labelColor
551
+
552
+ @labelColor.setter
553
+ def labelColor(self, c):
554
+ self._labelColor = QColor(c); self.update()