qpuiq 0.10__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.

Potentially problematic release.


This version of qpuiq might be problematic. Click here for more details.

Files changed (103) hide show
  1. PUI/PySide6/__init__.py +49 -0
  2. PUI/PySide6/application.py +58 -0
  3. PUI/PySide6/base.py +222 -0
  4. PUI/PySide6/button.py +21 -0
  5. PUI/PySide6/canvas.py +288 -0
  6. PUI/PySide6/checkbox.py +32 -0
  7. PUI/PySide6/combobox.py +75 -0
  8. PUI/PySide6/dialog.py +72 -0
  9. PUI/PySide6/divider.py +23 -0
  10. PUI/PySide6/image.py +30 -0
  11. PUI/PySide6/label.py +33 -0
  12. PUI/PySide6/layout.py +72 -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 +153 -0
  20. PUI/PySide6/splitter.py +25 -0
  21. PUI/PySide6/tab.py +39 -0
  22. PUI/PySide6/table.py +89 -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 +120 -0
  27. PUI/PySide6/window.py +81 -0
  28. PUI/__init__.py +46 -0
  29. PUI/common.py +20 -0
  30. PUI/decorator.py +20 -0
  31. PUI/dom.py +238 -0
  32. PUI/flet/__init__.py +21 -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/label.py +27 -0
  39. PUI/flet/layout.py +50 -0
  40. PUI/flet/progressbar.py +21 -0
  41. PUI/flet/radiobutton.py +27 -0
  42. PUI/flet/scroll.py +83 -0
  43. PUI/flet/tab.py +42 -0
  44. PUI/flet/text.py +55 -0
  45. PUI/flet/textfield.py +58 -0
  46. PUI/flet/window.py +25 -0
  47. PUI/interfaces.py +97 -0
  48. PUI/node.py +407 -0
  49. PUI/state.py +698 -0
  50. PUI/textual/__init__.py +34 -0
  51. PUI/textual/application.py +82 -0
  52. PUI/textual/base.py +113 -0
  53. PUI/textual/button.py +17 -0
  54. PUI/textual/checkbox.py +21 -0
  55. PUI/textual/label.py +36 -0
  56. PUI/textual/layout.py +48 -0
  57. PUI/textual/progressbar.py +17 -0
  58. PUI/textual/radiobutton.py +24 -0
  59. PUI/textual/scroll.py +72 -0
  60. PUI/textual/tab.py +75 -0
  61. PUI/textual/text.py +32 -0
  62. PUI/textual/textfield.py +49 -0
  63. PUI/textual/window.py +7 -0
  64. PUI/timeline.py +36 -0
  65. PUI/tkinter/__init__.py +43 -0
  66. PUI/tkinter/application.py +49 -0
  67. PUI/tkinter/base.py +68 -0
  68. PUI/tkinter/button.py +15 -0
  69. PUI/tkinter/canvas.py +49 -0
  70. PUI/tkinter/checkbox.py +27 -0
  71. PUI/tkinter/label.py +17 -0
  72. PUI/tkinter/layout.py +114 -0
  73. PUI/tkinter/progressbar.py +17 -0
  74. PUI/tkinter/radiobutton.py +26 -0
  75. PUI/tkinter/scroll.py +201 -0
  76. PUI/tkinter/tab.py +52 -0
  77. PUI/tkinter/text.py +20 -0
  78. PUI/tkinter/textfield.py +53 -0
  79. PUI/tkinter/window.py +51 -0
  80. PUI/utils.py +15 -0
  81. PUI/view.py +161 -0
  82. PUI/wx/__init__.py +19 -0
  83. PUI/wx/application.py +44 -0
  84. PUI/wx/base.py +202 -0
  85. PUI/wx/button.py +16 -0
  86. PUI/wx/canvas.py +255 -0
  87. PUI/wx/checkbox.py +25 -0
  88. PUI/wx/combobox.py +72 -0
  89. PUI/wx/dialog.py +66 -0
  90. PUI/wx/divider.py +19 -0
  91. PUI/wx/label.py +18 -0
  92. PUI/wx/layout.py +46 -0
  93. PUI/wx/progressbar.py +17 -0
  94. PUI/wx/radiobutton.py +27 -0
  95. PUI/wx/scroll.py +44 -0
  96. PUI/wx/text.py +23 -0
  97. PUI/wx/textfield.py +56 -0
  98. PUI/wx/window.py +58 -0
  99. qpuiq-0.10.dist-info/LICENSE.txt +21 -0
  100. qpuiq-0.10.dist-info/METADATA +227 -0
  101. qpuiq-0.10.dist-info/RECORD +103 -0
  102. qpuiq-0.10.dist-info/WHEEL +5 -0
  103. qpuiq-0.10.dist-info/top_level.txt +1 -0
PUI/tkinter/text.py ADDED
@@ -0,0 +1,20 @@
1
+ from .. import *
2
+ from .base import *
3
+
4
+ class Text(TkBaseWidget):
5
+ def __init__(self, text, selectable=False):
6
+ super().__init__()
7
+ self.text = text
8
+
9
+ def update(self, prev):
10
+ if prev and prev.ui:
11
+ self.ui = prev.ui
12
+ self.ui.config(text = self.text)
13
+ else:
14
+ self.ui = tk.Label(self.tkparent.inner, text=self.text, anchor="w", justify="left")
15
+
16
+ class Html(Text):
17
+ pui_supported = False
18
+
19
+ class MarkDown(Text):
20
+ pui_supported = False
@@ -0,0 +1,53 @@
1
+ from .. import *
2
+ from .base import *
3
+
4
+ class TextField(TkBaseWidget):
5
+ def __init__(self, model, edit_model=None):
6
+ super().__init__()
7
+ self.model = model
8
+ self.edit_model = edit_model
9
+ self.editing = False
10
+
11
+ def update(self, prev):
12
+ model_value = str(self.model.value)
13
+ if prev and prev.ui:
14
+ self.editing = prev.editing
15
+ self.variable = prev.variable
16
+ self.ui = prev.ui
17
+ self.curr_value = prev.curr_value
18
+ if self.curr_value.set(model_value) and not self.editing:
19
+ self.variable.set(model_value)
20
+ else:
21
+ self.variable = tk.StringVar(self.tkparent.inner, model_value)
22
+ self.variable.trace_add("write", self.on_variable_changed)
23
+ self.curr_value = Prop(model_value)
24
+ self.ui = tk.Entry(self.tkparent.inner, textvariable=self.variable)
25
+ self.ui.bind('<Return>', self.on_return)
26
+ self.ui.bind('<FocusOut>', self.on_focus_out)
27
+
28
+ if self.edit_model and not self.editing:
29
+ self.edit_model.value = model_value
30
+
31
+ super().update(prev)
32
+
33
+ def on_variable_changed(self, var, index, mode):
34
+ node = self.get_node()
35
+ node.editing = True
36
+ if node.edit_model:
37
+ node.edit_model.value = self.variable.get()
38
+ self._input()
39
+
40
+ def on_change(self):
41
+ node = self.get_node()
42
+ node.editing = False
43
+ value = self.variable.get()
44
+ node.model.value = value
45
+ if node.edit_model:
46
+ node.edit_model.value = value
47
+ self._change()
48
+
49
+ def on_return(self, e):
50
+ self.on_change()
51
+
52
+ def on_focus_out(self, e):
53
+ self.on_change()
PUI/tkinter/window.py ADDED
@@ -0,0 +1,51 @@
1
+ from .. import *
2
+ from .base import *
3
+
4
+ class Window(TkBaseWidget):
5
+ pui_terminal = False
6
+ def __init__(self, title=None, size=None, maximize=None, fullscreen=None):
7
+ super().__init__()
8
+ self.title = title
9
+ self.size = size
10
+ self.maximize = maximize
11
+ self.fullscreen = fullscreen
12
+
13
+ def update(self, prev):
14
+ if prev and prev.ui:
15
+ self.ui = prev.ui
16
+ self.curr_size = prev.curr_size
17
+ self.curr_maximize = prev.curr_maximize
18
+ self.curr_fullscreen = prev.curr_fullscreen
19
+ else:
20
+ self.ui = tk.Toplevel(self.parent.inner)
21
+ # self.ui.protocol("WM_DELETE_WINDOW", self.on_closing)
22
+ self.curr_size = Prop()
23
+ self.curr_maximize = Prop()
24
+ self.curr_fullscreen = Prop()
25
+
26
+ if self.curr_size.set(self.size):
27
+ self.ui.geometry("x".join([str(v) for v in self.size]))
28
+
29
+ if self.curr_maximize.set(self.maximize):
30
+ # https://stackoverflow.com/a/70061942
31
+ try:
32
+ self.ui.attributes('-zoomed', True)
33
+ except:
34
+ self.ui.state("zoomed")
35
+
36
+ if self.curr_fullscreen.set(self.fullscreen):
37
+ self.ui.attributes('-fullscreen', True)
38
+
39
+ if not self.title is None:
40
+ self.ui.title(self.title)
41
+
42
+ def on_closing(self):
43
+ self.get_node().tkparent.ui.destroy()
44
+
45
+ def addChild(self, idx, child):
46
+ if idx:
47
+ return
48
+ child.outer.pack(fill=tk.BOTH, expand=True)
49
+
50
+ def removeChild(self, idx, child):
51
+ child.outer.pack_forget()
PUI/utils.py ADDED
@@ -0,0 +1,15 @@
1
+ def trbl(d):
2
+ # https://www.w3schools.com/css/css_padding.asp
3
+ if isinstance(d, int) or isinstance(d, float):
4
+ return (d,d,d,d)
5
+ elif len(d) == 4: # top, right, bottom, left
6
+ return d
7
+ elif len(d) == 3: # top, right/left, bottom
8
+ return (d[0], d[1], d[2], d[1])
9
+ elif len(d) == 2: # top/bottom, right/left
10
+ return (d[0], d[1], d[0], d[1])
11
+ else:
12
+ raise RuntimeError(f"Unsupported format: {d}")
13
+
14
+ def trbl2ltrb(d):
15
+ return (d[3], d[0], d[1], d[2])
PUI/view.py ADDED
@@ -0,0 +1,161 @@
1
+ from .node import *
2
+ from .dom import *
3
+ from .state import StateMutationInViewBuilderError
4
+ import time
5
+
6
+ DEBUG = False
7
+
8
+ class PUIView(PUINode):
9
+ pui_virtual = True
10
+ pui_isview = True
11
+ __ALLVIEWS__ = []
12
+
13
+ @staticmethod
14
+ def reload():
15
+ for v in PUIView.__ALLVIEWS__:
16
+ if DEBUG:
17
+ print("reload", v.key)
18
+ v.redraw()
19
+
20
+ def __init__(self, *args):
21
+ self.frames = []
22
+ self.dirty = False
23
+ self.updating = False
24
+ super().__init__(*args)
25
+ PUIView.__ALLVIEWS__.append(self)
26
+
27
+ def __enter__(self):
28
+ if not hasattr(tls, "puistack"):
29
+ tls.puistack = []
30
+ tls.puistack.append(self)
31
+ # print("enter", type(self).__name__, id(self))
32
+ self.root.frames.append(self)
33
+ return self
34
+
35
+ def __exit__(self, ex_type, value, traceback):
36
+ tls.puistack.pop()
37
+ # print("exit", type(self).__name__, id(self))
38
+ self.root.frames.pop()
39
+ if ex_type is None: # don't consume exception
40
+ return self
41
+
42
+ def content(self):
43
+ return None
44
+
45
+ def dump(self):
46
+ if DEBUG:
47
+ print(f"content() start", self.key)
48
+ start = time.time()
49
+ with self as scope:
50
+ self.content()
51
+ if DEBUG:
52
+ print(f"content() time: {time.time()-start:.5f}", self.key)
53
+ return scope
54
+
55
+ def destroy(self, direct):
56
+ try:
57
+ PUIView.__ALLVIEWS__.remove(self)
58
+ except:
59
+ pass
60
+ return super().destroy(direct)
61
+
62
+ def redraw(self):
63
+ if self.retired_by or self.destroyed:
64
+ return
65
+ self.dirty = True
66
+ if self.updating:
67
+ return
68
+ self.updating = True
69
+ self.sync()
70
+
71
+ def wait(self):
72
+ """
73
+ Wait for the view to be updated.
74
+ """
75
+ while self.updating or self.dirty:
76
+ time.sleep(0.0001)
77
+
78
+ # Subview update entry point
79
+ def sync(self):
80
+ if not self.pui_virtual:
81
+ raise VDomError(f"sync() called on non-virtual node {self.key}")
82
+ if self.retired_by or self.destroyed:
83
+ return
84
+ self.dirty = False
85
+
86
+ dom_parent = (self.pui_dom_parent or self).get_node()
87
+ if DEBUG:
88
+ print(f"Sync subview {self.key}@{id(self)} retired_by={id(self.retired_by) if self.retired_by else None} destroyed={self.destroyed} dom_parent={dom_parent.key}@{id(dom_parent)}")
89
+ found, offset = dom_parent.findDomOffsetForNode(self)
90
+ if DEBUG:
91
+ print(f" found={found} offset={offset}")
92
+ if not found:
93
+ if DEBUG:
94
+ print(dom_parent.serialize(show_pyid=True, show_hierarchy=True))
95
+ offset = 0
96
+
97
+ last_children = self.children
98
+ try:
99
+ self.update()
100
+ except (StateMutationInViewBuilderError, VDomError):
101
+ raise
102
+ except:
103
+ # prevent crash in hot-reloading
104
+ self.children = last_children
105
+ import traceback
106
+ print("## <ERROR OF content() >", self.key, id(self))
107
+ traceback.print_exc()
108
+ print("## </ERROR OF content()>")
109
+
110
+ start = time.time()
111
+ if DEBUG:
112
+ print("sync() start", self.key)
113
+
114
+ if DEBUG:
115
+ print(f"offset for {self.key}@{id(self)} on {dom_parent.key}@{id(dom_parent)} is {offset}")
116
+ sync(self, dom_parent, offset, last_children, self.children)
117
+ if DEBUG:
118
+ print(f"sync() time: {time.time()-start:.5f}", self.key)
119
+
120
+ self.updating = False
121
+ if self.dirty:
122
+ self.redraw()
123
+
124
+ def update(self, prev=None):
125
+ if self.retired_by:
126
+ return
127
+ if self.destroyed:
128
+ return
129
+ if not prev:
130
+ if self.setup:
131
+ self.setup()
132
+ self.setup = None
133
+ else:
134
+ self.setup = None
135
+
136
+ if DEBUG:
137
+ print(f"update() {self.key}@{id(self)} prev={id(prev) if prev else None}")
138
+
139
+ if prev and prev is not self:
140
+ prev.retired_by = self
141
+ try:
142
+ print(f"retired {prev.key}@{id(prev)}")
143
+ PUIView.__ALLVIEWS__.remove(prev)
144
+ except:
145
+ pass
146
+
147
+ self.children = []
148
+ if DEBUG:
149
+ print(f"content() start", self.key)
150
+ start = time.time()
151
+ with self as scope: # init frame stack
152
+ self.content() # V-DOM builder
153
+ if DEBUG:
154
+ print(f"content() time: {time.time()-start:.5f}", self.key)
155
+
156
+ def setup(self):
157
+ pass
158
+
159
+ def run(self):
160
+ self.sync()
161
+ self.start()
PUI/wx/__init__.py ADDED
@@ -0,0 +1,19 @@
1
+ from .application import *
2
+ from .button import *
3
+ from .canvas import *
4
+ from .checkbox import *
5
+ from .combobox import *
6
+ from .dialog import *
7
+ from .divider import *
8
+ from .label import *
9
+ from .layout import *
10
+ from .progressbar import *
11
+ from .radiobutton import *
12
+ from .scroll import *
13
+ from .text import *
14
+ from .textfield import *
15
+ from .window import *
16
+
17
+ PUIView = WxPUIView
18
+
19
+ PUI_BACKEND = "wx"
PUI/wx/application.py ADDED
@@ -0,0 +1,44 @@
1
+ from .. import *
2
+ from .base import *
3
+
4
+ class Application(WxPUIView):
5
+ def __init__(self, icon=None):
6
+ super().__init__()
7
+ self.ui = None
8
+ self.icon = icon
9
+
10
+ def redraw(self):
11
+ if self.ui:
12
+ super().redraw()
13
+ else:
14
+ self.update(None)
15
+
16
+ def update(self, prev=None):
17
+ if not self.ui:
18
+ self.ui = wx.App()
19
+
20
+ super().update(prev)
21
+
22
+ def addChild(self, idx, child):
23
+ child.outer.Show()
24
+
25
+ def removeChild(self, idx, child):
26
+ child.outer.Close()
27
+
28
+ def start(self):
29
+ self.ui.MainLoop()
30
+
31
+ def PUIApp(func):
32
+ def func_wrapper(*args, **kwargs):
33
+ class PUIAppWrapper(Application):
34
+ def __init__(self, name):
35
+ self.name = name
36
+ super().__init__()
37
+
38
+ def content(self):
39
+ return func(*args, **kwargs)
40
+
41
+ ret = PUIAppWrapper(func.__name__)
42
+ return ret
43
+
44
+ return func_wrapper
PUI/wx/base.py ADDED
@@ -0,0 +1,202 @@
1
+ from .. import *
2
+
3
+ import wx
4
+
5
+ def int_to_wx_colour(color_int):
6
+ red = (color_int >> 16) & 0xFF
7
+ green = (color_int >> 8) & 0xFF
8
+ blue = color_int & 0xFF
9
+ return wx.Colour(red, green, blue)
10
+
11
+ def getWindow(n):
12
+ from .window import Window
13
+ from .scroll import Scroll
14
+ p = n
15
+ while p:
16
+ if isinstance(p, Scroll):
17
+ return p.ui
18
+ if isinstance(p, Window):
19
+ return p.ui
20
+ p = p.parent
21
+ raise RuntimeError("!!! getWindow returns None for", n.key if n else None)
22
+
23
+ class WxPUIView(PUIView):
24
+ pui_virtual = True
25
+ def __init__(self):
26
+ super().__init__()
27
+
28
+ def destroy(self, direct):
29
+ if self.ui: # PUIView doesn't have ui
30
+ self.ui.Destroy()
31
+ self.ui = None
32
+ super().destroy(direct)
33
+
34
+ def redraw(self):
35
+ wx.CallAfter(self.sync)
36
+
37
+ def update(self, prev=None):
38
+ if self.retired_by:
39
+ return
40
+ self.dirty = False
41
+ super().update(prev)
42
+ self.updating = False
43
+ if self.dirty:
44
+ self.update(prev)
45
+
46
+ class WXBase(PUINode):
47
+ scroll = False
48
+ container_x = False
49
+ container_y = False
50
+ strong_expand_x = False
51
+ strong_expand_y = False
52
+ weak_expand_x = False
53
+ weak_expand_y = False
54
+ nweak_expand_x = False
55
+ nweak_expand_y = False
56
+ strong_expand_x_children = 0
57
+ strong_expand_y_children = 0
58
+
59
+ @property
60
+ def expand_x(self):
61
+ return self.strong_expand_x or (self.weak_expand_x and not self.nweak_expand_x)
62
+
63
+ @property
64
+ def expand_y(self):
65
+ return self.strong_expand_y or (self.weak_expand_y and not self.nweak_expand_y)
66
+
67
+ def update(self, prev):
68
+ parent = self.wxparent
69
+ if parent:
70
+ if not parent.scroll and len(parent.children) == 1:
71
+ if parent.expand_x:
72
+ self.strong_expand_x = True
73
+ if parent.expand_y:
74
+ self.strong_expand_y = True
75
+
76
+ # request expanding from inside
77
+ if parent.container_x:
78
+ if parent.expand_y:
79
+ self.strong_expand_y = True
80
+ if self.layout_weight:
81
+ self.strong_expand_x = True
82
+ parent.strong_expand_x_children += 1
83
+ p = parent
84
+ while p:
85
+ if isinstance(p, WXBase):
86
+ p.weak_expand_x = True
87
+ if p==p.parent:
88
+ break
89
+ p = p.parent
90
+
91
+ if parent.container_y:
92
+ if parent.expand_x:
93
+ self.strong_expand_x = True
94
+ if self.layout_weight:
95
+ self.strong_expand_y = True
96
+ parent.strong_expand_y_children += 1
97
+ p = parent
98
+ while p:
99
+ if isinstance(p, WXBase):
100
+ p.weak_expand_y = True
101
+ if p==p.parent:
102
+ break
103
+ p = p.parent
104
+
105
+ if parent.strong_expand_x_children > 0:
106
+ self.nweak_expand_x = True
107
+ if parent.strong_expand_y_children > 0:
108
+ self.nweak_expand_y = True
109
+
110
+ else:
111
+ # mark root node as expanding
112
+ self.strong_expand_x = True
113
+ self.strong_expand_y = True
114
+
115
+ super().update(prev)
116
+
117
+ @property
118
+ def wxparent(self):
119
+ parent = self.parent
120
+ while not isinstance(parent, WXBase):
121
+ if parent==parent.parent:
122
+ parent = None
123
+ break
124
+ parent = parent.parent
125
+ return parent
126
+
127
+
128
+ class WxBaseWidget(WXBase):
129
+ pui_terminal = True
130
+
131
+ def __init__(self):
132
+ super().__init__()
133
+ self.layout_padding = (3, 3, 3, 3)
134
+
135
+ def update(self, prev):
136
+ super().update(prev)
137
+
138
+ if self.style_fontsize:
139
+ font = self.ui.GetFont()
140
+ font.SetPointSize(self.style_fontsize)
141
+ self.ui.SetFont(font)
142
+
143
+ # Set font color if specified
144
+ if self.style_color:
145
+ self.ui.SetForegroundColour(int_to_wx_colour(self.style_color))
146
+
147
+ def destroy(self, direct):
148
+ if self.ui is not None:
149
+ self.ui.Destroy()
150
+ self.ui = None
151
+ super().destroy(direct)
152
+
153
+ class WxBaseLayout(WXBase):
154
+ def __init__(self):
155
+ super().__init__()
156
+ if not isinstance(self.non_virtual_parent, WxBaseLayout):
157
+ self.layout_padding = (11,11,11,11)
158
+
159
+ def destroy(self, direct):
160
+ # self.ui.Destroy()
161
+ self.ui = None
162
+ super().destroy(direct)
163
+
164
+ def addChild(self, idx, child):
165
+ from .layout import Spacer
166
+ weight = child.layout_weight
167
+ if weight is None:
168
+ weight = 0
169
+ if not weight and self.container_x and child.expand_x:
170
+ weight = 1
171
+ if not weight and self.container_y and child.expand_y:
172
+ weight = 1
173
+ flag = wx.ALL
174
+
175
+ p = 0
176
+ if child.layout_padding:
177
+ p = max(child.layout_padding)
178
+ if isinstance(child, WxBaseLayout):
179
+ self.ui.Insert(idx, child.outer, proportion=weight, flag=flag|wx.EXPAND, border=p)
180
+ elif isinstance(child, WxBaseWidget):
181
+ if child.expand_x or child.expand_y or child.weak_expand_x or child.weak_expand_y:
182
+ flag |= wx.EXPAND
183
+ else:
184
+ flag |= wx.ALIGN_CENTER
185
+ self.ui.Insert(idx, child.outer, proportion=weight, flag=flag, border=p)
186
+ elif isinstance(child, Spacer):
187
+ self.ui.InsertStretchSpacer(idx, weight)
188
+
189
+ def removeChild(self, idx, child):
190
+ from .layout import Spacer
191
+ if isinstance(child, WxBaseLayout):
192
+ self.ui.Detach(idx)
193
+ elif isinstance(child, WxBaseWidget):
194
+ self.ui.Detach(idx)
195
+ elif isinstance(child, Spacer):
196
+ self.ui.Detach(idx)
197
+
198
+ def postSync(self):
199
+ if self.ui:
200
+ self.ui.Layout()
201
+ self.ui.Fit(getWindow(self.parent))
202
+ super().postSync()
PUI/wx/button.py ADDED
@@ -0,0 +1,16 @@
1
+ from .. import *
2
+ from .base import *
3
+
4
+ class Button(WxBaseWidget):
5
+ def __init__(self, text):
6
+ super().__init__()
7
+ self.text = text
8
+
9
+ def update(self, prev):
10
+ if prev and prev.ui:
11
+ self.ui = prev.ui
12
+ self.ui.SetLabel(self.text)
13
+ else:
14
+ self.ui = wx.Button(getWindow(self.parent), label=self.text)
15
+ self.ui.Bind(wx.EVT_BUTTON, self._clicked)
16
+ super().update(prev)