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,326 @@
1
+ ########################################################################
2
+ ## SPINN DESIGN CODE
3
+ # YOUTUBE: (SPINN TV) https://www.youtube.com/@SpinnTV
4
+ # WEBSITE: customwidgets.org
5
+ ########################################################################
6
+
7
+ ########################################################################
8
+ ## QCustomVideoPlayer - a poster-framed media/video player card.
9
+ ##
10
+ ## A rounded poster image with a big centred play button and a bottom control
11
+ ## bar (play / pause, elapsed / total time, a seek track). Feed it a poster
12
+ ## with setPoster(pm) and a length with `duration` ("mm:ss"); pressing play
13
+ ## advances a simulated playhead (a QTimer) so it demos without any media
14
+ ## backend, and clicking the track seeks. It emits playToggled(bool) and
15
+ ## seeked(float 0..1). Everything is painted (crisp at any size, no assets) and
16
+ ## every colour is a qproperty so it tracks the theme.
17
+ ########################################################################
18
+ from qtpy.QtCore import Qt, Property, Signal, QRectF, QTimer
19
+ from qtpy.QtGui import QColor, QPainter, QBrush, QPen, QPolygonF, QPixmap, QFont, QLinearGradient, QPainterPath
20
+ from qtpy.QtCore import QPointF
21
+ from qtpy.QtWidgets import QWidget, QSizePolicy
22
+
23
+
24
+ class QCustomVideoPlayer(QWidget):
25
+
26
+ playToggled = Signal(bool)
27
+ seeked = Signal(float)
28
+
29
+ WIDGET_ICON = "components/icons/play_circle.png"
30
+ WIDGET_TOOLTIP = "A poster-framed media / video player card"
31
+ WIDGET_MODULE = "Custom_Widgets.QCustomVideoPlayer"
32
+ WIDGET_DOM_XML = """
33
+ <ui language='c++'>
34
+ <widget class='QCustomVideoPlayer' name='customVideoPlayer'>
35
+ <property name='geometry'><rect><x>0</x><y>0</y><width>360</width><height>210</height></rect></property>
36
+ </widget>
37
+ </ui>
38
+ """
39
+ __catalog__ = {
40
+ "name": "QCustomVideoPlayer",
41
+ "props": {
42
+ "duration": {"type": "string", "default": "02:45"},
43
+ "progress": {"type": "float", "default": 0.0},
44
+ "playing": {"type": "bool", "default": False},
45
+ "radius": {"type": "int", "default": 18},
46
+ "accentColor": {"type": "color", "default": "#1b74e4"},
47
+ "posterColor": {"type": "color", "default": "#222838"},
48
+ "barColor": {"type": "color", "default": "#e6ffffff"},
49
+ "trackColor": {"type": "color", "default": "#4dffffff"},
50
+ "textColor": {"type": "color", "default": "#ffffff"},
51
+ },
52
+ "signals": ["playToggled", "seeked"],
53
+ # Intentionally no tokens_used: this widget resolves no token roles.
54
+ }
55
+
56
+ def __init__(self, parent=None):
57
+ super().__init__(parent)
58
+ self.setObjectName("QCustomVideoPlayer")
59
+ self._poster = QPixmap()
60
+ self._poster_color = QColor("#222838")
61
+ self._accent = QColor("#1b74e4")
62
+ self._bar = QColor(255, 255, 255, 230)
63
+ self._track = QColor(255, 255, 255, 77)
64
+ self._text = QColor("#ffffff")
65
+ self._radius = 18
66
+ self._duration = "02:45"
67
+ self._total_ms = self._parse(self._duration)
68
+ self._progress = 0.0
69
+ self._playing = False
70
+ self._bar_h = 40
71
+
72
+ self._timer = QTimer(self)
73
+ self._timer.setInterval(200)
74
+ self._timer.timeout.connect(self._tick)
75
+
76
+ self.setMinimumSize(220, 140)
77
+ self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
78
+ self.setCursor(Qt.PointingHandCursor)
79
+ self.setMouseTracking(True)
80
+
81
+ # ------------------------------------------------------------------ #
82
+ ## Data API
83
+ # ------------------------------------------------------------------ #
84
+ def setPoster(self, pm):
85
+ self._poster = pm if isinstance(pm, QPixmap) else QPixmap(str(pm))
86
+ self.update()
87
+
88
+ def setPlaying(self, v):
89
+ v = bool(v)
90
+ if v == self._playing:
91
+ return
92
+ self._playing = v
93
+ if v:
94
+ self._timer.start()
95
+ else:
96
+ self._timer.stop()
97
+ self.playToggled.emit(v)
98
+ self.update()
99
+
100
+ def toggle(self):
101
+ self.setPlaying(not self._playing)
102
+
103
+ @staticmethod
104
+ def _parse(text):
105
+ try:
106
+ parts = [int(x) for x in str(text).split(":")]
107
+ except ValueError:
108
+ return 0
109
+ secs = 0
110
+ for x in parts:
111
+ secs = secs * 60 + x
112
+ return secs * 1000
113
+
114
+ @staticmethod
115
+ def _fmt(ms):
116
+ s = max(0, int(ms // 1000))
117
+ return "%d:%02d" % (s // 60, s % 60)
118
+
119
+ def _tick(self):
120
+ if self._total_ms <= 0:
121
+ return
122
+ self._progress = min(1.0, self._progress + self._timer.interval() / self._total_ms)
123
+ if self._progress >= 1.0:
124
+ self.setPlaying(False)
125
+ self.update()
126
+
127
+ # ------------------------------------------------------------------ #
128
+ ## Geometry helpers
129
+ # ------------------------------------------------------------------ #
130
+ def _barRect(self):
131
+ return QRectF(0, self.height() - self._bar_h, self.width(), self._bar_h)
132
+
133
+ def _trackRect(self):
134
+ br = self._barRect()
135
+ x0 = br.left() + 84
136
+ x1 = br.right() - 16
137
+ return QRectF(x0, br.center().y() - 2, max(1.0, x1 - x0), 4)
138
+
139
+ def _centerBtnRect(self):
140
+ d = min(self.width(), self.height()) * 0.26
141
+ d = max(44, min(80, d))
142
+ return QRectF((self.width() - d) / 2.0, (self.height() - self._bar_h - d) / 2.0, d, d)
143
+
144
+ # ------------------------------------------------------------------ #
145
+ ## Paint
146
+ # ------------------------------------------------------------------ #
147
+ def paintEvent(self, e):
148
+ p = QPainter(self)
149
+ p.setRenderHint(QPainter.Antialiasing, True)
150
+ p.setRenderHint(QPainter.SmoothPixmapTransform, True)
151
+ full = QRectF(0.5, 0.5, self.width() - 1, self.height() - 1)
152
+ path = QPainterPath()
153
+ path.addRoundedRect(full, self._radius, self._radius)
154
+ p.setClipPath(path)
155
+
156
+ # poster (aspect-fill) or flat colour
157
+ if not self._poster.isNull():
158
+ scaled = self._poster.size().scaled(self.width(), self.height(), Qt.KeepAspectRatioByExpanding)
159
+ x = (self.width() - scaled.width()) / 2.0
160
+ y = (self.height() - scaled.height()) / 2.0
161
+ p.drawPixmap(QRectF(x, y, scaled.width(), scaled.height()).toRect(), self._poster)
162
+ else:
163
+ p.fillRect(full, self._poster_color)
164
+ # subtle darken for control legibility
165
+ p.fillRect(full, QColor(0, 0, 0, 40))
166
+
167
+ # centre play/pause button
168
+ cb = self._centerBtnRect()
169
+ p.setPen(Qt.NoPen)
170
+ halo = QColor(self._accent)
171
+ p.setBrush(QBrush(halo))
172
+ p.drawEllipse(cb)
173
+ p.setBrush(QBrush(self._text))
174
+ c = cb.center()
175
+ d = cb.width()
176
+ if self._playing:
177
+ bw = d * 0.11
178
+ gap = d * 0.10
179
+ bh = d * 0.32
180
+ p.drawRoundedRect(QRectF(c.x() - gap - bw, c.y() - bh / 2, bw, bh), bw / 3, bw / 3)
181
+ p.drawRoundedRect(QRectF(c.x() + gap, c.y() - bh / 2, bw, bh), bw / 3, bw / 3)
182
+ else:
183
+ s = d * 0.28
184
+ p.drawPolygon(QPolygonF([QPointF(c.x() - s * 0.45, c.y() - s * 0.62),
185
+ QPointF(c.x() - s * 0.45, c.y() + s * 0.62),
186
+ QPointF(c.x() + s * 0.68, c.y())]))
187
+
188
+ # bottom control bar gradient
189
+ br = self._barRect()
190
+ g = QLinearGradient(0, br.top(), 0, br.bottom())
191
+ g.setColorAt(0.0, QColor(0, 0, 0, 0))
192
+ g.setColorAt(1.0, QColor(0, 0, 0, 150))
193
+ p.fillRect(br, QBrush(g))
194
+
195
+ # small play glyph on the bar
196
+ p.setBrush(QBrush(self._bar))
197
+ gx, gy = br.left() + 20, br.center().y()
198
+ if self._playing:
199
+ p.drawRoundedRect(QRectF(gx - 5, gy - 6, 3.4, 12), 1.4, 1.4)
200
+ p.drawRoundedRect(QRectF(gx + 1.6, gy - 6, 3.4, 12), 1.4, 1.4)
201
+ else:
202
+ p.drawPolygon(QPolygonF([QPointF(gx - 4, gy - 6), QPointF(gx - 4, gy + 6), QPointF(gx + 6, gy)]))
203
+
204
+ # time text
205
+ f = QFont(self.font())
206
+ f.setPointSizeF(9.5)
207
+ f.setWeight(QFont.DemiBold)
208
+ p.setFont(f)
209
+ p.setPen(QPen(self._text))
210
+ elapsed = self._fmt(self._progress * self._total_ms)
211
+ total = self._fmt(self._total_ms)
212
+ p.drawText(QRectF(br.left() + 38, br.top(), 60, br.height()),
213
+ Qt.AlignVCenter | Qt.AlignLeft, elapsed)
214
+ p.drawText(QRectF(br.right() - 54, br.top(), 42, br.height()),
215
+ Qt.AlignVCenter | Qt.AlignRight, total)
216
+
217
+ # seek track
218
+ tr = self._trackRect()
219
+ p.setPen(Qt.NoPen)
220
+ p.setBrush(QBrush(self._track))
221
+ p.drawRoundedRect(tr, tr.height() / 2, tr.height() / 2)
222
+ fill = QRectF(tr.left(), tr.top(), tr.width() * self._progress, tr.height())
223
+ p.setBrush(QBrush(self._accent))
224
+ p.drawRoundedRect(fill, tr.height() / 2, tr.height() / 2)
225
+ # playhead knob
226
+ kx = tr.left() + tr.width() * self._progress
227
+ p.setBrush(QBrush(self._text))
228
+ p.drawEllipse(QPointF(kx, tr.center().y()), 5, 5)
229
+ p.end()
230
+
231
+ def mousePressEvent(self, e):
232
+ pos = e.position()
233
+ tr = self._trackRect()
234
+ hit = QRectF(tr.left() - 4, tr.top() - 10, tr.width() + 8, tr.height() + 20)
235
+ if hit.contains(pos):
236
+ frac = max(0.0, min(1.0, (pos.x() - tr.left()) / tr.width()))
237
+ self._progress = frac
238
+ self.seeked.emit(frac)
239
+ self.update()
240
+ else:
241
+ self.toggle()
242
+ e.accept()
243
+
244
+ # ------------------------------------------------------------------ #
245
+ ## Designer properties
246
+ # ------------------------------------------------------------------ #
247
+ @Property(str)
248
+ def duration(self):
249
+ return self._duration
250
+
251
+ @duration.setter
252
+ def duration(self, v):
253
+ self._duration = str(v)
254
+ self._total_ms = self._parse(self._duration)
255
+ self.update()
256
+
257
+ @Property(float)
258
+ def progress(self):
259
+ return self._progress
260
+
261
+ @progress.setter
262
+ def progress(self, v):
263
+ self._progress = max(0.0, min(1.0, float(v)))
264
+ self.update()
265
+
266
+ @Property(bool)
267
+ def playing(self):
268
+ return self._playing
269
+
270
+ @playing.setter
271
+ def playing(self, v):
272
+ self.setPlaying(v)
273
+
274
+ @Property(int)
275
+ def radius(self):
276
+ return self._radius
277
+
278
+ @radius.setter
279
+ def radius(self, v):
280
+ self._radius = max(0, int(v))
281
+ self.update()
282
+
283
+ @Property(QColor)
284
+ def accentColor(self):
285
+ return self._accent
286
+
287
+ @accentColor.setter
288
+ def accentColor(self, c):
289
+ self._accent = QColor(c)
290
+ self.update()
291
+
292
+ @Property(QColor)
293
+ def posterColor(self):
294
+ return self._poster_color
295
+
296
+ @posterColor.setter
297
+ def posterColor(self, c):
298
+ self._poster_color = QColor(c)
299
+ self.update()
300
+
301
+ @Property(QColor)
302
+ def barColor(self):
303
+ return self._bar
304
+
305
+ @barColor.setter
306
+ def barColor(self, c):
307
+ self._bar = QColor(c)
308
+ self.update()
309
+
310
+ @Property(QColor)
311
+ def trackColor(self):
312
+ return self._track
313
+
314
+ @trackColor.setter
315
+ def trackColor(self, c):
316
+ self._track = QColor(c)
317
+ self.update()
318
+
319
+ @Property(QColor)
320
+ def textColor(self):
321
+ return self._text
322
+
323
+ @textColor.setter
324
+ def textColor(self, c):
325
+ self._text = QColor(c)
326
+ self.update()
@@ -0,0 +1 @@
1
+ """Pro widgets: media."""
@@ -0,0 +1,112 @@
1
+ Metadata-Version: 2.4
2
+ Name: QT-PyQt-PySide-Custom-Widgets-Pro
3
+ Version: 1.1.0
4
+ Summary: Commercial Pro widgets (DataTable Pro, ...) for QT-PyQt-PySide-Custom-Widgets.
5
+ Author: Khamisi Kibet / SpinnCompany
6
+ License-Expression: LicenseRef-Proprietary
7
+ Project-URL: Homepage, https://github.com/SpinnCompany/QT-PyQt-PySide-Custom-Widgets
8
+ Project-URL: Documentation, https://spinncompany.github.io/Docs-QT-PyQt-PySide-Custom-Widgets/
9
+ Project-URL: Issues, https://github.com/SpinnCompany/QT-PyQt-PySide-Custom-Widgets/issues
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Environment :: X11 Applications :: Qt
13
+ Classifier: Operating System :: POSIX :: Linux
14
+ Classifier: Operating System :: MacOS :: MacOS X
15
+ Classifier: Operating System :: Microsoft :: Windows
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3.14
23
+ Classifier: Topic :: Software Development :: User Interfaces
24
+ Classifier: Topic :: Software Development :: Widget Sets
25
+ Requires-Python: >=3.10
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: QT-PyQt-PySide-Custom-Widgets>=2.6.0
29
+ Requires-Dist: qtpy
30
+ Provides-Extra: dev
31
+ Requires-Dist: pytest; extra == "dev"
32
+ Dynamic: license-file
33
+
34
+ # Custom Widgets Pro
35
+
36
+ Commercial widgets for
37
+ [QT-PyQt-PySide-Custom-Widgets](https://github.com/SpinnCompany/QT-PyQt-PySide-Custom-Widgets),
38
+ the 164-widget PySide6 library — starting with **DataTable Pro**, the data
39
+ table for real workloads.
40
+
41
+ ```bash
42
+ pip install QT-PyQt-PySide-Custom-Widgets-Pro
43
+ ```
44
+
45
+ Ships as native-compiled wheels for **Python 3.10–3.14** on Windows, macOS
46
+ and Linux (no readable source). Requires the free core **2.3.0 or newer**.
47
+
48
+ ## DataTable Pro
49
+
50
+ Built on the free `QCustomDataTable` — same API, same renderers, same
51
+ design-token theming — and adds what production data needs:
52
+
53
+ - **Virtualization** — lazy row windows over 100k+ rows or streaming
54
+ sources via a `DataProvider`; scrolling fetches, nothing materialises
55
+ up front.
56
+ - **Server-side sort & filter push-down** — the header drives your
57
+ backend, not a client-side sort of one loaded window.
58
+ - **Grouping with aggregates** —
59
+ `groupBy(["plan"], aggregates={"mrr": "sum"})` gives collapsible group
60
+ headers with computed totals.
61
+ - **Pivot (cross-tab)**, **frozen columns**, **inline editing with
62
+ validators**, and **CSV/XLSX export** that walks the full result set.
63
+
64
+ ```python
65
+ from custom_widgets_pro import QCustomDataTablePro # extends QCustomDataTable
66
+ ```
67
+
68
+ Guides: [DataTable](https://spinncompany.github.io/Docs-QT-PyQt-PySide-Custom-Widgets/Widgets/QCustomDataTable)
69
+ · [Grouping & Pivot](https://spinncompany.github.io/Docs-QT-PyQt-PySide-Custom-Widgets/Usage-Examples/DataTableGroupingPivot)
70
+
71
+ ## Licensing
72
+
73
+ Install freely — without an entitlement the package runs in **unlicensed
74
+ dev/eval mode**, so you can evaluate everything today. A plan from
75
+ [customwidgets.org/pricing](https://customwidgets.org/pricing/) or an
76
+ active [Patreon membership](https://www.patreon.com/c/spinntv) issues a
77
+ licence token:
78
+
79
+ ```bash
80
+ custom-widgets-pro activate <licence-token> # validates once, then caches
81
+ custom-widgets-pro status # or --refresh to re-check online
82
+ ```
83
+
84
+ Or set it in the environment: `export CUSTOM_WIDGETS_PRO_LICENSE=...`
85
+
86
+ - **Royalty-free in your applications** — end users never need a plan; no
87
+ runtime check, no per-copy fee.
88
+ - **Perpetual fallback** — versions obtained while subscribed stay
89
+ licensed forever; the plan buys updates and support.
90
+ - **The GPL question, answered in writing** — the free core is GPLv3, and
91
+ the Pro licence includes the copyright holder's additional permission,
92
+ so combining the core with Pro and with *your* application does not pull
93
+ your application under the GPL.
94
+
95
+ Each plan covers a number of devices; activating on a new machine claims a
96
+ seat, and you can free seats from your account. Validated entitlements are
97
+ cached locally with a 14-day offline grace period.
98
+
99
+ | Variable | Purpose |
100
+ |---|---|
101
+ | `CUSTOM_WIDGETS_PRO_LICENSE` | licence token from your account |
102
+ | `CUSTOM_WIDGETS_PRO_API_URL` | billing API base URL (staging / self-host) |
103
+ | `CUSTOM_WIDGETS_PRO_NO_CHECK` | skip the check (CI of licensed users) |
104
+
105
+ The full terms ship in `LICENSE`. This package contains only original code
106
+ — no third-party fonts, icons, or vendored source.
107
+
108
+ ## Links
109
+
110
+ - [Documentation](https://spinncompany.github.io/Docs-QT-PyQt-PySide-Custom-Widgets/)
111
+ - [Plans](https://customwidgets.org/pricing/) · [Patreon](https://www.patreon.com/c/spinntv) · [YouTube](https://www.youtube.com/@SpinnTV)
112
+ - [Free core on PyPI](https://pypi.org/project/QT-PyQt-PySide-Custom-Widgets/)
@@ -0,0 +1,45 @@
1
+ custom_widgets_pro/__init__.py,sha256=zrg5tGb7unP-00KGT55uR_p-3Zafg0Wja5oJyCpFhFk,3166
2
+ custom_widgets_pro/_catalog.py,sha256=mPLYkjfulMFsNEDZzXnWXDmwn6cqBRBMWttOfIGRHII,880
3
+ custom_widgets_pro/_cli.py,sha256=GSctYvjPgoKwdklOSK2xLHTZ2gtWYmsXfL_weUeIsyA,4672
4
+ custom_widgets_pro/_license.py,sha256=Gfg7dZwNOr95b4Z4nL67w02fY_M2hQ8V5Rcm1pEBNdg,16810
5
+ custom_widgets_pro/_version.py,sha256=kK_GCAyxtrb1a6VkdSl1Yijr5TZt_AXvtAmoeHz67w8,610
6
+ custom_widgets_pro/datatable/__init__.py,sha256=SBes1tGmvvYg14EcL_Pq1OVyfh08ntRPOCg6E3VShuU,744
7
+ custom_widgets_pro/datatable/datatable_pro.py,sha256=gwunyTjA_HeWB6aq4Ob-5o-8D1GRFQ5V7EjBtOvzQdw,13681
8
+ custom_widgets_pro/datatable/export.py,sha256=CUtjhlehZZMx0dua_Wcx7H_qcGLy0yhw3jfSjI18e_Y,5940
9
+ custom_widgets_pro/datatable/frozen_view.py,sha256=cfgUJ_-NWBxHqNi7OCF3Eu3zhB5lFGXdLnRIkKuwwzY,4482
10
+ custom_widgets_pro/datatable/grouping.py,sha256=zqsnALy4eJIwVVFZqdKZ0W1ZOqSNV-t4daPuTkPUL_8,11884
11
+ custom_widgets_pro/datatable/pivot.py,sha256=z2r1ZHM995C2BzVpW7GLXuklQYjjpUBhayed5ecMTYQ,3881
12
+ custom_widgets_pro/datatable/provider.py,sha256=hdTLpJAtBtLKw4h0Mvah-Zx5NwkMJdu5F8zGr9-VlYQ,3816
13
+ custom_widgets_pro/datatable/virtual_model.py,sha256=jmNwb-WzjtMuW0gUXD-BqyTSb5rdkeSmWO9lQcuFegA,19282
14
+ custom_widgets_pro/widgets/__init__.py,sha256=OpAzMieY-5gP9PCWczgbnvsCwzueLfEk1tN_F2H8ptg,301
15
+ custom_widgets_pro/widgets/charts/QCustomBeeswarm.py,sha256=Pu7CPt4maI3HWy5DRgFg9lnoUZ1n78TegqLv8ymcTrY,11496
16
+ custom_widgets_pro/widgets/charts/QCustomBubbleChart.py,sha256=LHlKW24_yF6SsgRw3o5YJ39Y8A0XHr4OJPSAONfAlQM,25995
17
+ custom_widgets_pro/widgets/charts/QCustomCandlestickChart.py,sha256=dk1pKMoH60n69TajC1EZg6e6YEgDQqott-pdtogNSx4,19136
18
+ custom_widgets_pro/widgets/charts/QCustomDivergingBarChart.py,sha256=VfLEnpb0lmbKWzDvpqgOn4F_y5LE-dOTLmk3puFD09s,16162
19
+ custom_widgets_pro/widgets/charts/QCustomDotMatrix.py,sha256=ax0nd9SjjOMxv7SJFoAi5ZYH5idVBDN8CBZAZc5zFcs,9778
20
+ custom_widgets_pro/widgets/charts/QCustomFunnelChart.py,sha256=AIGYTXEJTQOL4gJZ5nR6K8eaTCxM6OabTUQROa1hpqM,18253
21
+ custom_widgets_pro/widgets/charts/QCustomGanttChart.py,sha256=Qs0hsNM-1UbVgOPlu_xRpJUEC6sf4MCZjlzfStBIxs4,14936
22
+ custom_widgets_pro/widgets/charts/QCustomHeatmap.py,sha256=4kSV0NlNRhG1vJgUbMx2iPG4X0gXZOmhvizDmCa9wYo,20302
23
+ custom_widgets_pro/widgets/charts/QCustomRadarChart.py,sha256=1kE6nZQODzulzP4HUy-Pbnksd1z816y3mh0n8X2zm6Y,22527
24
+ custom_widgets_pro/widgets/charts/QCustomRadialBars.py,sha256=fZanfZiAm-HdxCHc13GQ9FVlErsZz6PGhpu-QlGrSII,15838
25
+ custom_widgets_pro/widgets/charts/QCustomRadialLines.py,sha256=e3xg0mrUuFULaXMz5nm6MT8rnhrc2CcPJQcLJx8mln8,20538
26
+ custom_widgets_pro/widgets/charts/QCustomRangeBarChart.py,sha256=a3FoDUGkbf9M4fDniy-uFSKPsxGNXBR_BX8KRtPgmRE,19436
27
+ custom_widgets_pro/widgets/charts/QCustomSankey.py,sha256=9ajVqalW-0pqB39am0t3LMvsdVGUGoVTOYI6WG5c1wM,20318
28
+ custom_widgets_pro/widgets/charts/QCustomScatterChart.py,sha256=uXH7nikzs5qWfhMvv5u5dHidKaDfXBpYnsAVMB30GWA,24421
29
+ custom_widgets_pro/widgets/charts/__init__.py,sha256=Z2kAhDVp5frYVxYKz2tnrEwPqBLJcRA3ONPpwiy58RA,27
30
+ custom_widgets_pro/widgets/data/QCustomCodeEditor.py,sha256=OvK5128pXMZnY2ig1-3055esBiUCuafeELoOERxdFpE,13372
31
+ custom_widgets_pro/widgets/data/QCustomNodeGraph.py,sha256=iX1LPRKjlUD5fH2H7DjhuZHR9Nf8PLY2fZBROR27NFg,38412
32
+ custom_widgets_pro/widgets/data/QCustomRichTextEditor.py,sha256=sZXQA2q7lp87loh3sG8oPzNF1KNzCfqYZG-KR5-79-k,7055
33
+ custom_widgets_pro/widgets/data/QCustomTableToolbar.py,sha256=YEvGH0cVE3Q8tyzDQVHYK_AaF-xG_ypW8PY2-MbFKf8,23913
34
+ custom_widgets_pro/widgets/data/__init__.py,sha256=f7zYThNVgFaZAw7dEHKBG1vJfH08bwyzSssWt3VZQJQ,25
35
+ custom_widgets_pro/widgets/media/QCustomImageViewer.py,sha256=1KDJS4EeuDLWAoqux8877E_3KAt__RQVGsFKp-sSRwo,10753
36
+ custom_widgets_pro/widgets/media/QCustomMediaGrid.py,sha256=IUCnrETqXSgnF8Bj0dl6S_5P_0PBWPs2B8t1bI0zP4Y,6839
37
+ custom_widgets_pro/widgets/media/QCustomMediaTimeline.py,sha256=b6G6ipLbz_49OmY9Dx1P_i1BfG46SqG6wwTOLNAIof4,21660
38
+ custom_widgets_pro/widgets/media/QCustomVideoPlayer.py,sha256=D_0CdoIB9_ifbLkraVFxADE9ixz_qSuYPBbuGUdyces,11381
39
+ custom_widgets_pro/widgets/media/__init__.py,sha256=7Syhr1_JDekVXsguM0QAQj_vZU-FPjNNlRLdB0r5FaE,26
40
+ qt_pyqt_pyside_custom_widgets_pro-1.1.0.dist-info/licenses/LICENSE,sha256=g-YFQhOGGEuLoXKl2mZpv3IO5_4teUU1qQc2bAnpzVo,4661
41
+ qt_pyqt_pyside_custom_widgets_pro-1.1.0.dist-info/METADATA,sha256=UzNzgDvjaTuXdcorx2GOu6cp3EG-zsXakA9jvfb0XxQ,4962
42
+ qt_pyqt_pyside_custom_widgets_pro-1.1.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
43
+ qt_pyqt_pyside_custom_widgets_pro-1.1.0.dist-info/entry_points.txt,sha256=AXclIu23sY0Hcj_b1bVTiHrRgcOyB0xBK8Whh3zQOhE,68
44
+ qt_pyqt_pyside_custom_widgets_pro-1.1.0.dist-info/top_level.txt,sha256=Peycfv0yaWJX20IdCEVKUOsrTOguQOL3e6GVi4s6tsg,19
45
+ qt_pyqt_pyside_custom_widgets_pro-1.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ custom-widgets-pro = custom_widgets_pro._cli:main
@@ -0,0 +1,91 @@
1
+ Custom Widgets Pro — Commercial License Agreement
2
+
3
+ Copyright (c) 2026 Khamisi Kibet / SpinnCompany ("Licensor").
4
+ All rights reserved. Contact: support@customwidgets.org
5
+
6
+ This package ("the Software") is proprietary. It is licensed, not sold. By
7
+ installing or using the Software you agree to these terms.
8
+
9
+ 1. DEFINITIONS
10
+ "Plan" means an active entitlement purchased at https://customwidgets.org
11
+ (Stripe) or granted through an active Patreon membership
12
+ (https://www.patreon.com/c/spinntv). "Licensee" means the individual or
13
+ organization holding the Plan. "Application" means software developed by
14
+ the Licensee that incorporates the Software as an integrated component.
15
+
16
+ 2. LICENSE GRANT
17
+ While a Plan is active, Licensor grants Licensee a non-exclusive,
18
+ non-transferable, worldwide license to:
19
+ a. install and use the Software for development on the number of seats
20
+ the Plan allows;
21
+ b. incorporate the Software into any number of Applications; and
22
+ c. distribute the Software ONLY as an integrated, non-separable part of
23
+ an Application, royalty-free. End users of an Application need no Plan.
24
+ Patreon-granted entitlements at tiers marked personal/non-commercial
25
+ license development and distribution of non-commercial Applications only;
26
+ commercial distribution requires a commercial Plan.
27
+
28
+ 3. PERPETUAL FALLBACK
29
+ Versions of the Software obtained while a Plan was active remain licensed
30
+ under these terms after the Plan ends. Updates, new versions, and support
31
+ require an active Plan.
32
+
33
+ 4. RESTRICTIONS
34
+ Licensee must not:
35
+ a. distribute, publish, resell, rent, or sublicense the Software on a
36
+ standalone basis, or as part of any product whose primary value is the
37
+ Software itself (a component library, SDK, or development tool);
38
+ b. share, publish, or pool license tokens or entitlement credentials;
39
+ c. remove or alter proprietary notices;
40
+ d. circumvent, disable, or interfere with entitlement verification,
41
+ except that the Software's own unlicensed evaluation mode may be used
42
+ for evaluation; or
43
+ e. reverse engineer, decompile, or disassemble the Software except to the
44
+ extent such restriction is prohibited by applicable law.
45
+
46
+ 5. FREE CORE — ADDITIONAL PERMISSION (GPL EXCEPTION)
47
+ The Software depends on the package "QT-PyQt-PySide-Custom-Widgets" (the
48
+ "Free Core"), which is licensed to the public under GPL-3.0-only.
49
+ As copyright holder of the Free Core, Licensor grants Licensee this
50
+ additional permission: combining the Free Core with the Software and/or
51
+ with Licensee's Applications does not subject the Software or those
52
+ Applications to the terms of the GPL, and Licensee is not required to
53
+ license Applications under the GPL by reason of that combination. This
54
+ permission does not otherwise limit Licensee's GPL rights in the Free
55
+ Core, and does not extend to third-party GPL components (see clause 6).
56
+
57
+ 6. THIRD-PARTY COMPONENTS
58
+ The Software runs on Qt via PySide6 (LGPL-3.0) and other third-party
59
+ packages, each under its own license. Licensee is responsible for
60
+ complying with those licenses in its Applications (dynamic linking of
61
+ PySide6 in the ordinary way satisfies the LGPL for typical deployments).
62
+
63
+ 7. OWNERSHIP
64
+ The Software is licensed, not sold. Licensor retains all right, title,
65
+ and interest in the Software. Feedback may be used by Licensor without
66
+ restriction.
67
+
68
+ 8. TERMINATION
69
+ This license terminates automatically on material breach. On termination
70
+ Licensee must stop using and distributing the Software, except that
71
+ Applications already distributed to end users may continue to be used by
72
+ those end users, and clause 3 survives for versions lawfully obtained
73
+ before the breach-free termination of a Plan.
74
+
75
+ 9. NO WARRANTY
76
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
77
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO MERCHANTABILITY, FITNESS FOR A
78
+ PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
79
+
80
+ 10. LIMITATION OF LIABILITY
81
+ TO THE MAXIMUM EXTENT PERMITTED BY LAW, LICENSOR'S TOTAL LIABILITY
82
+ ARISING OUT OF OR RELATED TO THE SOFTWARE SHALL NOT EXCEED THE AMOUNTS
83
+ PAID BY LICENSEE FOR THE PLAN IN THE TWELVE MONTHS PRECEDING THE CLAIM,
84
+ AND LICENSOR SHALL NOT BE LIABLE FOR INDIRECT, INCIDENTAL, SPECIAL, OR
85
+ CONSEQUENTIAL DAMAGES.
86
+
87
+ 11. GENERAL
88
+ These terms are governed by the laws of Licensor's principal place of
89
+ business, excluding conflict-of-law rules. If any clause is held
90
+ unenforceable, the remainder stays in effect. These terms are the entire
91
+ agreement concerning the Software and supersede prior drafts.
@@ -0,0 +1 @@
1
+ custom_widgets_pro