qpuiq 0.23__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 (104) hide show
  1. PUI/PySide6/__init__.py +49 -0
  2. PUI/PySide6/application.py +58 -0
  3. PUI/PySide6/base.py +285 -0
  4. PUI/PySide6/button.py +21 -0
  5. PUI/PySide6/canvas.py +345 -0
  6. PUI/PySide6/checkbox.py +32 -0
  7. PUI/PySide6/combobox.py +85 -0
  8. PUI/PySide6/dialog.py +72 -0
  9. PUI/PySide6/divider.py +23 -0
  10. PUI/PySide6/image.py +48 -0
  11. PUI/PySide6/label.py +33 -0
  12. PUI/PySide6/layout.py +141 -0
  13. PUI/PySide6/matplotlib.py +23 -0
  14. PUI/PySide6/mdi.py +33 -0
  15. PUI/PySide6/menu.py +85 -0
  16. PUI/PySide6/modal.py +132 -0
  17. PUI/PySide6/progressbar.py +17 -0
  18. PUI/PySide6/radiobutton.py +29 -0
  19. PUI/PySide6/scroll.py +155 -0
  20. PUI/PySide6/splitter.py +25 -0
  21. PUI/PySide6/tab.py +39 -0
  22. PUI/PySide6/table.py +147 -0
  23. PUI/PySide6/text.py +35 -0
  24. PUI/PySide6/textfield.py +62 -0
  25. PUI/PySide6/toolbar.py +57 -0
  26. PUI/PySide6/tree.py +290 -0
  27. PUI/PySide6/window.py +82 -0
  28. PUI/__init__.py +46 -0
  29. PUI/common.py +26 -0
  30. PUI/decorator.py +20 -0
  31. PUI/dom.py +263 -0
  32. PUI/flet/__init__.py +22 -0
  33. PUI/flet/application.py +42 -0
  34. PUI/flet/base.py +37 -0
  35. PUI/flet/button.py +20 -0
  36. PUI/flet/canvas.py +86 -0
  37. PUI/flet/checkbox.py +23 -0
  38. PUI/flet/divider.py +14 -0
  39. PUI/flet/label.py +27 -0
  40. PUI/flet/layout.py +50 -0
  41. PUI/flet/progressbar.py +21 -0
  42. PUI/flet/radiobutton.py +27 -0
  43. PUI/flet/scroll.py +83 -0
  44. PUI/flet/tab.py +42 -0
  45. PUI/flet/text.py +55 -0
  46. PUI/flet/textfield.py +58 -0
  47. PUI/flet/window.py +25 -0
  48. PUI/interfaces.py +97 -0
  49. PUI/node.py +432 -0
  50. PUI/state.py +711 -0
  51. PUI/textual/__init__.py +35 -0
  52. PUI/textual/application.py +82 -0
  53. PUI/textual/base.py +148 -0
  54. PUI/textual/button.py +17 -0
  55. PUI/textual/checkbox.py +21 -0
  56. PUI/textual/label.py +36 -0
  57. PUI/textual/layout.py +52 -0
  58. PUI/textual/progressbar.py +17 -0
  59. PUI/textual/radiobutton.py +24 -0
  60. PUI/textual/scroll.py +74 -0
  61. PUI/textual/tab.py +75 -0
  62. PUI/textual/text.py +32 -0
  63. PUI/textual/textfield.py +55 -0
  64. PUI/textual/window.py +7 -0
  65. PUI/timeline.py +36 -0
  66. PUI/tkinter/__init__.py +43 -0
  67. PUI/tkinter/application.py +49 -0
  68. PUI/tkinter/base.py +68 -0
  69. PUI/tkinter/button.py +15 -0
  70. PUI/tkinter/canvas.py +52 -0
  71. PUI/tkinter/checkbox.py +27 -0
  72. PUI/tkinter/label.py +17 -0
  73. PUI/tkinter/layout.py +114 -0
  74. PUI/tkinter/progressbar.py +17 -0
  75. PUI/tkinter/radiobutton.py +26 -0
  76. PUI/tkinter/scroll.py +201 -0
  77. PUI/tkinter/tab.py +52 -0
  78. PUI/tkinter/text.py +20 -0
  79. PUI/tkinter/textfield.py +53 -0
  80. PUI/tkinter/window.py +51 -0
  81. PUI/utils.py +15 -0
  82. PUI/view.py +161 -0
  83. PUI/wx/__init__.py +19 -0
  84. PUI/wx/application.py +44 -0
  85. PUI/wx/base.py +246 -0
  86. PUI/wx/button.py +16 -0
  87. PUI/wx/canvas.py +255 -0
  88. PUI/wx/checkbox.py +25 -0
  89. PUI/wx/combobox.py +81 -0
  90. PUI/wx/dialog.py +66 -0
  91. PUI/wx/divider.py +19 -0
  92. PUI/wx/label.py +18 -0
  93. PUI/wx/layout.py +52 -0
  94. PUI/wx/progressbar.py +19 -0
  95. PUI/wx/radiobutton.py +27 -0
  96. PUI/wx/scroll.py +55 -0
  97. PUI/wx/text.py +23 -0
  98. PUI/wx/textfield.py +66 -0
  99. PUI/wx/window.py +64 -0
  100. qpuiq-0.23.dist-info/LICENSE.txt +21 -0
  101. qpuiq-0.23.dist-info/METADATA +234 -0
  102. qpuiq-0.23.dist-info/RECORD +104 -0
  103. qpuiq-0.23.dist-info/WHEEL +5 -0
  104. qpuiq-0.23.dist-info/top_level.txt +1 -0
PUI/node.py ADDED
@@ -0,0 +1,432 @@
1
+ import threading
2
+ from .utils import *
3
+ from .dom import *
4
+
5
+ tls = threading.local()
6
+
7
+ class PuiViewNotFoundError(Exception): pass
8
+
9
+ def find_puiview():
10
+ try:
11
+ return tls.puistack[-1]
12
+ except:
13
+ raise PuiViewNotFoundError()
14
+
15
+ class PUIEvent():
16
+ def __str__(self):
17
+ return str(self.__dict__)
18
+
19
+
20
+ class PUINode():
21
+ # To prevent crashes when we use a UI component not supported by the selected backend, this is useful when you are trying to support multiple backends.
22
+ pui_supported = True
23
+
24
+ # Tell DOM syncer not to go deeper into the node, it should be True for non-container elements
25
+ pui_terminal = False
26
+
27
+ # Menu and window-like UI elements, are out-of-order, so they are moved to the end of siblings before DOM syncing to simplify the process
28
+ pui_outoforder = False
29
+
30
+ # When enabled, children are added in reverse order, used by Stack
31
+ pui_reversed_order = False
32
+
33
+ # Used by PUIView
34
+ pui_isview = False
35
+
36
+ # Used by TimelineView, TabView, Sub-View or other nodes don't link to a real UI hierarchy
37
+ # Children of virtual nodes will be promoted to the same level as the virtual node, addChild/removeChild won't be called for virtual nodes
38
+ pui_virtual = False
39
+
40
+ # When disabled, children are not allowed to be moved when DOM syncing, QSpacerItem is an example of non-movable node
41
+ pui_movable = True
42
+
43
+ # Used by grid layout, when enabled, sort children by grid_{row,column,rowspan,columnspan} before DOM sync
44
+ pui_grid_layout = False
45
+
46
+ def __init__(self, *args):
47
+ from .view import PUIView
48
+
49
+ if not hasattr(self, "name"):
50
+ self.name = None
51
+
52
+ self.destroyed = False
53
+ self.retired_by = None
54
+ self.pui_dom_parent = None
55
+ self._debug = 0
56
+ self._id = ""
57
+ self._tag = ""
58
+
59
+ self.layout_weight = None
60
+ self.layout_width = None
61
+ self.layout_height = None
62
+ self.layout_padding = None
63
+ self.layout_margin = None
64
+ self.style_color = None
65
+ self.style_bgcolor = None
66
+ self.style_fontsize = None
67
+ self.style_fontweight = None
68
+ self.style_fontfamily = None
69
+ self.grid_row = None
70
+ self.grid_column = None
71
+ self.grid_rowspan = None
72
+ self.grid_columnspan = None
73
+
74
+ self._onChanged = None
75
+ self._onClicked = None
76
+ self._onDblClicked = None
77
+ self._onInput = None
78
+ self._onKeyPress = None
79
+ self._onMouseDown = None
80
+ self._onMouseUp = None
81
+ self._onMouseMove = None
82
+ self._onWheel = None
83
+ self._onDragEntered = None
84
+ self._onDropped = None
85
+
86
+ self.ui = None
87
+ self.args = args
88
+ try:
89
+ self.root = find_puiview()
90
+ self.parent = self.root.frames[-1]
91
+ except PuiViewNotFoundError:
92
+ self.root = self
93
+ self.parent = self
94
+ self.frames = []
95
+
96
+ if isinstance(self, PUIView):
97
+ self.root = self
98
+
99
+ self.genKey()
100
+
101
+ self.children = []
102
+
103
+ if self.parent is self:
104
+ self._path = tuple()
105
+ else:
106
+ self._path = self.parent._path + tuple([len(self.parent.children)])
107
+ self.parent.children.append(self)
108
+
109
+ # print(type(self).__name__, self._path, "parent=", self.parent._path)
110
+
111
+ def findDomOffsetForNode(self, node):
112
+ if self is node:
113
+ return True, 0
114
+ offset = 0
115
+ for c in self.children:
116
+ if c is node:
117
+ return True, offset
118
+ if c.pui_virtual:
119
+ found, off = c.findDomOffsetForNode(node)
120
+ offset += off
121
+ if found:
122
+ return True, offset
123
+ elif not c.pui_outoforder:
124
+ offset += 1
125
+ return False, offset
126
+
127
+ def genKey(self):
128
+ # key has to be relative to PUIView, so that it can be identical when a sub-PUIView is updated individually
129
+ self.key = "|".join([x.name or type(x).__name__ for x in self.root.frames]+[self.name or type(self).__name__])
130
+ if self.grid_row is not None and self.grid_column is not None:
131
+ self.key += f":grid:{self.grid_row},{self.grid_column},{self.grid_rowspan},{self.grid_columnspan}"
132
+ if hasattr(self, "_internal_tag"):
133
+ self.key += f"%{self._internal_tag}"
134
+ if self._id:
135
+ self.key += f"#{self._id}"
136
+
137
+ def __enter__(self):
138
+ # print("enter", type(self).__name__, id(self))
139
+ self.root.frames.append(self)
140
+ return self
141
+
142
+ def __exit__(self, ex_type, value, traceback):
143
+ # print("exit", type(self).__name__, id(self))
144
+ self.root.frames.pop()
145
+ if ex_type is None: # don't consume exception
146
+ return self
147
+
148
+ @property
149
+ def non_virtual_parent(self):
150
+ p = self.parent
151
+ while p.pui_virtual:
152
+ p = p.parent
153
+ return p
154
+
155
+ @property
156
+ def inner(self):
157
+ if self.ui:
158
+ return self.ui
159
+ return self.parent.inner
160
+
161
+ @property
162
+ def outer(self):
163
+ if self.ui:
164
+ return self.ui
165
+ if self.children:
166
+ return self.children[0].outer
167
+ return None
168
+
169
+ def comment(self):
170
+ return None
171
+
172
+ def update(self, prev):
173
+ if prev and prev is not self:
174
+ prev.retired_by = self
175
+
176
+ def postUpdate(self):
177
+ pass
178
+
179
+ def preSync(self):
180
+ pass
181
+
182
+ def postSync(self):
183
+ pass
184
+
185
+ def destroy(self, direct):
186
+ self.root = None
187
+ self.parent = None
188
+ self.children = []
189
+
190
+ def addChild(self, idx, child):
191
+ pass
192
+
193
+ def removeChild(self, idx, child):
194
+ pass
195
+
196
+ def debug(self, level=1):
197
+ self._debug = level
198
+ return self
199
+
200
+ def id(self, name):
201
+ self._id = name
202
+ self.genKey()
203
+ return self
204
+
205
+ def tag(self, tag):
206
+ self._tag = tag
207
+ return self
208
+
209
+ def get_node(self):
210
+ node = self
211
+ while node.retired_by:
212
+ node = node.retired_by
213
+ if node is not self:
214
+ self.retired_by = node
215
+ return node
216
+
217
+ def __repr__(self):
218
+ return self.serialize()
219
+
220
+ def serialize(self, show_key=True, show_pyid=False, show_hierarchy=False, layout_debug=False):
221
+ segs = []
222
+ headline = [
223
+ " "*len(self._path),
224
+ self.name or type(self).__name__,
225
+ ]
226
+ if show_pyid:
227
+ headline.append(f"@{id(self)}")
228
+ if self.children:
229
+ headline.append(" {")
230
+
231
+ # print view key
232
+ if show_key:
233
+ headline.append(" # Key: ")
234
+ headline.append(self.key)
235
+ headline.append(" # Tag: ")
236
+ headline.append(self._tag)
237
+
238
+ if show_hierarchy:
239
+ headline.append(f" # parent={id(self.parent) if self.parent else None}")
240
+
241
+ if layout_debug:
242
+ headline.append(" # Layout:")
243
+ if hasattr(self, "expand_x"):
244
+ headline.append(f" expand_x={self.expand_x}")
245
+ if hasattr(self, "expand_y"):
246
+ headline.append(f" expand_y={self.expand_y}")
247
+ if hasattr(self, "strong_expand_x"):
248
+ headline.append(f" strong_expand_x={self.strong_expand_x}")
249
+ if hasattr(self, "strong_expand_y"):
250
+ headline.append(f" strong_expand_y={self.strong_expand_y}")
251
+ if hasattr(self, "weak_expand_x"):
252
+ headline.append(f" weak_expand_x={self.weak_expand_x}")
253
+ if hasattr(self, "weak_expand_y"):
254
+ headline.append(f" weak_expand_y={self.weak_expand_y}")
255
+ if hasattr(self, "nweak_expand_x"):
256
+ headline.append(f" nweak_expand_x={self.nweak_expand_x}")
257
+ if hasattr(self, "nweak_expand_y"):
258
+ headline.append(f" nweak_expand_y={self.nweak_expand_y}")
259
+ if hasattr(self, "strong_expand_x_children"):
260
+ headline.append(f" strong_expand_x_children={self.strong_expand_x_children}")
261
+ if hasattr(self, "strong_expand_y_children"):
262
+ headline.append(f" strong_expand_y_children={self.strong_expand_y_children}")
263
+
264
+ if self.children:
265
+ headline.append("\n")
266
+ segs.append("".join(headline))
267
+
268
+ comment = self.comment()
269
+ if comment:
270
+ segs.append(" "*(len(self._path)+1))
271
+ segs.append("# ")
272
+ segs.append(comment)
273
+ segs.append("\n")
274
+
275
+ if self.children:
276
+ for i,c in enumerate(self.children):
277
+ if i > 0:
278
+ segs.append("\n")
279
+ segs.append(c.serialize(show_key=show_key, show_pyid=show_pyid, show_hierarchy=show_hierarchy, layout_debug=layout_debug))
280
+ segs.append("\n")
281
+ segs.append("".join([" "*len(self._path), "}"]))
282
+ return "".join(segs)
283
+
284
+ def layout(self, width=None, height=None, weight=None, padding=None, margin=None):
285
+ if not width is None:
286
+ self.layout_width = width
287
+ if not height is None:
288
+ self.layout_height = height
289
+ if not weight is None:
290
+ self.layout_weight = weight
291
+ if not padding is None:
292
+ self.layout_padding = trbl(padding)
293
+ if not margin is None:
294
+ self.layout_margin = trbl(margin)
295
+
296
+ return self
297
+
298
+ def style(self, color=None, bgColor=None, fontSize=None, fontWeight=None, fontFamily=None):
299
+ if not color is None:
300
+ self.style_color = color
301
+ if not bgColor is None:
302
+ self.style_bgcolor = bgColor
303
+ if not fontSize is None:
304
+ self.style_fontsize = fontSize
305
+ if not fontWeight is None:
306
+ self.style_fontweight = fontWeight
307
+ if not fontFamily is None:
308
+ self.style_fontfamily = fontFamily
309
+
310
+ return self
311
+
312
+ def grid(self, row=None, column=None, rowspan=None, columnspan=None):
313
+ if row is not None:
314
+ self.grid_row = row
315
+ if column is not None:
316
+ self.grid_column = column
317
+ if rowspan is not None:
318
+ self.grid_rowspan = rowspan
319
+ if columnspan is not None:
320
+ self.grid_columnspan = columnspan
321
+ self.genKey()
322
+ return self
323
+
324
+ def dragEnter(self, callback, *cb_args, **cb_kwargs):
325
+ self._onDragEntered = callback, cb_args, cb_kwargs
326
+ return self
327
+
328
+ def drop(self, callback, *cb_args, **cb_kwargs):
329
+ self._onDropped = callback, cb_args, cb_kwargs
330
+ return self
331
+
332
+ def click(self, callback, *cb_args, **cb_kwargs):
333
+ self._onClicked = callback, cb_args, cb_kwargs
334
+ return self
335
+
336
+ def _clicked(self, e=None, *args, **kwargs):
337
+ node = self.get_node()
338
+ if node._onClicked:
339
+ cb, cb_args, cb_kwargs = node._onClicked
340
+ cb(e, *cb_args, **cb_kwargs)
341
+
342
+ def dblclick(self, callback, *cb_args, **cb_kwargs):
343
+ self._onDblClicked = callback, cb_args, cb_kwargs
344
+ return self
345
+
346
+ def _dblclicked(self, e, *args, **kwargs):
347
+ node = self.get_node()
348
+ if node._onDblClicked:
349
+ cb, cb_args, cb_kwargs = node._onDblClicked
350
+ cb(e, *cb_args, **cb_kwargs)
351
+
352
+ def change(self, callback, *cb_args, **cb_kwargs):
353
+ self._onChanged = callback, cb_args, cb_kwargs
354
+ return self
355
+
356
+ def _change(self, e, *args, **kwargs):
357
+ node = self.get_node()
358
+ if node._onChanged:
359
+ cb, cb_args, cb_kwargs = node._onChanged
360
+ cb(e, *cb_args, **cb_kwargs)
361
+
362
+ def input(self, callback, *cb_args, **cb_kwargs):
363
+ self._onInput = callback, cb_args, cb_kwargs
364
+ return self
365
+
366
+ def _input(self, e, *args, **kwargs):
367
+ node = self.get_node()
368
+ if node._onInput:
369
+ cb, cb_args, cb_kwargs = node._onInput
370
+ cb(e, *cb_args, **cb_kwargs)
371
+
372
+ def mousedown(self, callback, *cb_args, **cb_kwargs):
373
+ self._onMouseDown = callback, cb_args, cb_kwargs
374
+ return self
375
+
376
+ def _mousedown(self, e, *args, **kwargs):
377
+ node = self.get_node()
378
+ if node._onMouseDown:
379
+ cb, cb_args, cb_kwargs = node._onMouseDown
380
+ cb(e, *cb_args, **cb_kwargs)
381
+
382
+ def mouseup(self, callback, *cb_args, **cb_kwargs):
383
+ self._onMouseUp = callback, cb_args, cb_kwargs
384
+ return self
385
+
386
+ def _mouseup(self, e, *args, **kwargs):
387
+ node = self.get_node()
388
+ if node._onMouseUp:
389
+ cb, cb_args, cb_kwargs = node._onMouseUp
390
+ cb(e, *cb_args, **cb_kwargs)
391
+
392
+ def mousemove(self, callback, *cb_args, **cb_kwargs):
393
+ self._onMouseMove = callback, cb_args, cb_kwargs
394
+ return self
395
+
396
+ def _mousemove(self, e, *args, **kwargs):
397
+ node = self.get_node()
398
+ if node._onMouseMove:
399
+ cb, cb_args, cb_kwargs = node._onMouseMove
400
+ cb(e, *cb_args, **cb_kwargs)
401
+
402
+ def wheel(self, callback, *cb_args, **cb_kwargs):
403
+ self._onWheel = callback, cb_args, cb_kwargs
404
+ return self
405
+
406
+ def _wheel(self, e, *args, **kwargs):
407
+ node = self.get_node()
408
+ if node._onWheel:
409
+ cb, cb_args, cb_kwargs = node._onWheel
410
+ cb(e, *cb_args, **cb_kwargs)
411
+
412
+ def keypress(self, callback, *cb_args, **cb_kwargs):
413
+ self._onKeyPress = callback, cb_args, cb_kwargs
414
+ return self
415
+
416
+ def _keypress(self, e, *args, **kwargs):
417
+ node = self.get_node()
418
+ if node._onKeyPress:
419
+ cb, cb_args, cb_kwargs = node._onKeyPress
420
+ cb(e, *cb_args, **cb_kwargs)
421
+
422
+ def flet(self, **kwargs):
423
+ return self
424
+
425
+ def textual(self, **kwargs):
426
+ return self
427
+
428
+ def tkinter(self, **kwargs):
429
+ return self
430
+
431
+ def qt(self, **kwargs):
432
+ return self