qpuiq 0.10__py3-none-any.whl → 0.12__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.
- PUI/PySide6/base.py +42 -0
- PUI/PySide6/table.py +71 -13
- PUI/PySide6/textfield.py +4 -2
- PUI/PySide6/tree.py +166 -9
- PUI/__init__.py +1 -1
- PUI/flet/textfield.py +3 -1
- PUI/node.py +12 -0
- PUI/state.py +6 -3
- PUI/textual/textfield.py +4 -2
- PUI/tkinter/textfield.py +3 -1
- PUI/wx/textfield.py +3 -2
- {qpuiq-0.10.dist-info → qpuiq-0.12.dist-info}/METADATA +17 -2
- {qpuiq-0.10.dist-info → qpuiq-0.12.dist-info}/RECORD +16 -16
- {qpuiq-0.10.dist-info → qpuiq-0.12.dist-info}/WHEEL +1 -1
- {qpuiq-0.10.dist-info → qpuiq-0.12.dist-info}/LICENSE.txt +0 -0
- {qpuiq-0.10.dist-info → qpuiq-0.12.dist-info}/top_level.txt +0 -0
PUI/PySide6/base.py
CHANGED
|
@@ -72,6 +72,19 @@ class QtPUIView(PUIView):
|
|
|
72
72
|
self.qt_params[k] = v
|
|
73
73
|
return self
|
|
74
74
|
|
|
75
|
+
class EventFilter(QtCore.QObject):
|
|
76
|
+
def __init__(self):
|
|
77
|
+
super().__init__()
|
|
78
|
+
self.node = None
|
|
79
|
+
|
|
80
|
+
def eventFilter(self, obj, event):
|
|
81
|
+
node = self.node.get_node()
|
|
82
|
+
if event.type() == QtCore.QEvent.DragEnter:
|
|
83
|
+
return node.handleDragEnterEvent(event)
|
|
84
|
+
elif event.type() == QtCore.QEvent.Drop:
|
|
85
|
+
return node.handleDropEvent(event)
|
|
86
|
+
return super().eventFilter(obj, event)
|
|
87
|
+
|
|
75
88
|
class QtBaseWidget(PUINode):
|
|
76
89
|
pui_terminal = True
|
|
77
90
|
|
|
@@ -89,6 +102,12 @@ class QtBaseWidget(PUINode):
|
|
|
89
102
|
def update(self, prev=None):
|
|
90
103
|
super().update(prev)
|
|
91
104
|
|
|
105
|
+
if prev:
|
|
106
|
+
self.eventFilter = prev.eventFilter
|
|
107
|
+
else:
|
|
108
|
+
self.eventFilter = EventFilter()
|
|
109
|
+
self.eventFilter.node = self
|
|
110
|
+
|
|
92
111
|
sizePolicy = self.ui.sizePolicy()
|
|
93
112
|
if self.layout_width is not None:
|
|
94
113
|
sizePolicy.setHorizontalPolicy(QtWidgets.QSizePolicy.Preferred)
|
|
@@ -102,6 +121,29 @@ class QtBaseWidget(PUINode):
|
|
|
102
121
|
|
|
103
122
|
_apply_params(self.ui, self)
|
|
104
123
|
|
|
124
|
+
def postUpdate(self):
|
|
125
|
+
if self.ui:
|
|
126
|
+
if self._onDropped:
|
|
127
|
+
self.ui.setAcceptDrops(True)
|
|
128
|
+
self.ui.installEventFilter(self.eventFilter)
|
|
129
|
+
else:
|
|
130
|
+
self.ui.setAcceptDrops(False)
|
|
131
|
+
super().postUpdate()
|
|
132
|
+
|
|
133
|
+
def handleDragEnterEvent(self, event):
|
|
134
|
+
if self._onDragEntered:
|
|
135
|
+
self._onDragEntered[0](event, *self._onDragEntered[1], **self._onDragEntered[2])
|
|
136
|
+
else:
|
|
137
|
+
event.setDropAction(QtCore.Qt.CopyAction)
|
|
138
|
+
event.accept()
|
|
139
|
+
|
|
140
|
+
def handleDropEvent(self, event):
|
|
141
|
+
if self._onDropped:
|
|
142
|
+
self._onDropped[0](event, *self._onDropped[1], **self._onDropped[2])
|
|
143
|
+
else:
|
|
144
|
+
print("Dropped", event)
|
|
145
|
+
event.ignore()
|
|
146
|
+
|
|
105
147
|
def qtSizeHint(self):
|
|
106
148
|
node = self.get_node()
|
|
107
149
|
if not node.ui:
|
PUI/PySide6/table.py
CHANGED
|
@@ -49,8 +49,45 @@ class QtTableModelAdapter(QtCore.QAbstractTableModel):
|
|
|
49
49
|
return self.model.columnCount()
|
|
50
50
|
|
|
51
51
|
|
|
52
|
+
class QtTableNodeModelAdapter(QtCore.QAbstractTableModel):
|
|
53
|
+
def __init__(self, children):
|
|
54
|
+
super().__init__()
|
|
55
|
+
self.children = children
|
|
56
|
+
|
|
57
|
+
def data(self, index, role):
|
|
58
|
+
if role == QtCore.Qt.DisplayRole:
|
|
59
|
+
data = self.children[index.row()].children[index.column()].data
|
|
60
|
+
if isinstance(data, BaseBinding):
|
|
61
|
+
return str(data.value)
|
|
62
|
+
return data
|
|
63
|
+
return None
|
|
64
|
+
|
|
65
|
+
def setData(self, index, value, role):
|
|
66
|
+
if role == QtCore.Qt.EditRole:
|
|
67
|
+
n = self.children[index.row()].children[index.column()]
|
|
68
|
+
if isinstance(n.data, BaseBinding):
|
|
69
|
+
n.data.value = value
|
|
70
|
+
else:
|
|
71
|
+
n._set(value)
|
|
72
|
+
return True
|
|
73
|
+
|
|
74
|
+
def flags(self, index):
|
|
75
|
+
flags = super().flags(index)
|
|
76
|
+
n = self.children[index.row()].children[index.column()]
|
|
77
|
+
if isinstance(n.data, BaseBinding) or n._set_callback:
|
|
78
|
+
flags |= QtCore.Qt.ItemIsEditable
|
|
79
|
+
return flags
|
|
80
|
+
|
|
81
|
+
def rowCount(self, index):
|
|
82
|
+
return len(self.children)
|
|
83
|
+
|
|
84
|
+
def columnCount(self, index):
|
|
85
|
+
if self.children:
|
|
86
|
+
return len(self.children[0].children)
|
|
87
|
+
return 0
|
|
88
|
+
|
|
52
89
|
class Table(QtBaseWidget):
|
|
53
|
-
def __init__(self, model, autofit=True):
|
|
90
|
+
def __init__(self, model=None, autofit=True):
|
|
54
91
|
super().__init__()
|
|
55
92
|
self.layout_weight = 1
|
|
56
93
|
self.model = model
|
|
@@ -67,23 +104,44 @@ class Table(QtBaseWidget):
|
|
|
67
104
|
self.curr_model = Prop()
|
|
68
105
|
self.ui = QtWidgets.QTableView()
|
|
69
106
|
|
|
70
|
-
if self.model
|
|
71
|
-
self.
|
|
72
|
-
|
|
73
|
-
|
|
107
|
+
if self.model:
|
|
108
|
+
if self.model.columnHeader is None:
|
|
109
|
+
self.ui.horizontalHeader().hide()
|
|
110
|
+
else:
|
|
111
|
+
self.ui.horizontalHeader().show()
|
|
74
112
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
113
|
+
if self.model.rowHeader is None:
|
|
114
|
+
self.ui.verticalHeader().hide()
|
|
115
|
+
else:
|
|
116
|
+
self.ui.verticalHeader().show()
|
|
79
117
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
118
|
+
if self.curr_model.set(self.model):
|
|
119
|
+
self.qt_model = QtTableModelAdapter(self.model)
|
|
120
|
+
self.ui.setModel(self.qt_model)
|
|
121
|
+
else:
|
|
122
|
+
self.qt_model.refresh()
|
|
83
123
|
else:
|
|
84
|
-
self.
|
|
124
|
+
self.ui.horizontalHeader().hide()
|
|
125
|
+
self.ui.verticalHeader().hide()
|
|
126
|
+
self.qt_model = QtTableNodeModelAdapter(self.children)
|
|
127
|
+
self.ui.setModel(self.qt_model)
|
|
85
128
|
|
|
86
129
|
if self.autofit:
|
|
87
130
|
self.ui.resizeColumnsToContents()
|
|
88
131
|
|
|
89
132
|
super().update(prev)
|
|
133
|
+
|
|
134
|
+
class TableNode(PUINode):
|
|
135
|
+
def __init__(self, data=""):
|
|
136
|
+
super().__init__()
|
|
137
|
+
self._set_callback = None
|
|
138
|
+
self.data = data
|
|
139
|
+
|
|
140
|
+
def set(self, cb, *args, **kwargs):
|
|
141
|
+
self._set_callback = (cb, args, kwargs)
|
|
142
|
+
return self
|
|
143
|
+
|
|
144
|
+
def _set(self, data):
|
|
145
|
+
if self._set_callback:
|
|
146
|
+
cb, args, kwargs = self._set_callback
|
|
147
|
+
cb(data, *args, **kwargs)
|
PUI/PySide6/textfield.py
CHANGED
|
@@ -53,10 +53,12 @@ class TextField(QtBaseWidget):
|
|
|
53
53
|
|
|
54
54
|
def on_textchanged(self):
|
|
55
55
|
node = self.get_node()
|
|
56
|
-
node.editing = True
|
|
57
56
|
value = self.ui.text()
|
|
58
57
|
if node.edit_model:
|
|
59
|
-
|
|
58
|
+
node.editing = True
|
|
59
|
+
node.edit_model.value = value
|
|
60
|
+
else:
|
|
61
|
+
node.model.value = value
|
|
60
62
|
e = PUIEvent()
|
|
61
63
|
e.value = value
|
|
62
64
|
self._input(e)
|
PUI/PySide6/tree.py
CHANGED
|
@@ -6,6 +6,7 @@ class QAbstractItemModelAdapter(QtCore.QAbstractItemModel):
|
|
|
6
6
|
def __init__(self, model: "BaseTreeAdapter"):
|
|
7
7
|
super().__init__()
|
|
8
8
|
self.model = model
|
|
9
|
+
self.node = None
|
|
9
10
|
|
|
10
11
|
def index(self, row, column, parent = QtCore.QModelIndex()):
|
|
11
12
|
parent_node = parent.internalPointer() if parent.isValid() else None
|
|
@@ -14,6 +15,27 @@ class QAbstractItemModelAdapter(QtCore.QAbstractItemModel):
|
|
|
14
15
|
return self.createIndex(row, column, child)
|
|
15
16
|
return QtCore.QModelIndex()
|
|
16
17
|
|
|
18
|
+
def flags(self, index):
|
|
19
|
+
if not index.isValid():
|
|
20
|
+
return QtCore.Qt.ItemIsDropEnabled
|
|
21
|
+
|
|
22
|
+
defaultFlags = super().flags(index)
|
|
23
|
+
|
|
24
|
+
return defaultFlags | QtCore.Qt.ItemIsDragEnabled | QtCore.Qt.ItemIsDropEnabled | QtCore.Qt.ItemIsEditable
|
|
25
|
+
|
|
26
|
+
def canDropMimeData(self, data, action, row, column, parent):
|
|
27
|
+
if parent.isValid():
|
|
28
|
+
pass
|
|
29
|
+
else:
|
|
30
|
+
return bool(self.node._onDropped)
|
|
31
|
+
|
|
32
|
+
def dropMimeData(self, data, action, row, column, parent):
|
|
33
|
+
if parent.isValid():
|
|
34
|
+
pass
|
|
35
|
+
else:
|
|
36
|
+
event = QtGui.QDropEvent(QtCore.QPoint(0,0), action, data, QtCore.Qt.MouseButton.LeftButton, QtCore.Qt.KeyboardModifier.NoModifier, QtCore.QEvent.Drop)
|
|
37
|
+
self.node._onDropped[0](event, *self.node._onDropped[1], **self.node._onDropped[2])
|
|
38
|
+
|
|
17
39
|
def parent(self, index):
|
|
18
40
|
if not index.isValid():
|
|
19
41
|
return QModelIndex()
|
|
@@ -42,9 +64,94 @@ class QAbstractItemModelAdapter(QtCore.QAbstractItemModel):
|
|
|
42
64
|
parent_node = parent.internalPointer() if parent.isValid() else None
|
|
43
65
|
return self.model.rowCount(parent_node) > 0
|
|
44
66
|
|
|
67
|
+
def clicked(self, node):
|
|
68
|
+
self.model.clicked(node)
|
|
69
|
+
|
|
70
|
+
def dblclicked(self, node):
|
|
71
|
+
self.model.dblclicked(node)
|
|
72
|
+
|
|
73
|
+
def expanded(self, node):
|
|
74
|
+
self.model.expanded(node)
|
|
75
|
+
|
|
76
|
+
def collapsed(self, node):
|
|
77
|
+
self.model.collapsed(node)
|
|
78
|
+
|
|
79
|
+
class QTreeNodeModelAdapter(QtCore.QAbstractItemModel):
|
|
80
|
+
def __init__(self, rootnode):
|
|
81
|
+
super().__init__()
|
|
82
|
+
self.node = None
|
|
83
|
+
self.rootnode = rootnode
|
|
84
|
+
|
|
85
|
+
def index(self, row, column, parent = QtCore.QModelIndex()):
|
|
86
|
+
parent_node = parent.internalPointer() if parent.isValid() else self.rootnode
|
|
87
|
+
if 0 <= row and row < len(parent_node.children):
|
|
88
|
+
child = parent_node.children[row]
|
|
89
|
+
return self.createIndex(row, column, child)
|
|
90
|
+
return QtCore.QModelIndex()
|
|
91
|
+
|
|
92
|
+
def flags(self, index):
|
|
93
|
+
if not index.isValid():
|
|
94
|
+
return QtCore.Qt.ItemIsDropEnabled
|
|
95
|
+
|
|
96
|
+
defaultFlags = super().flags(index)
|
|
97
|
+
|
|
98
|
+
return defaultFlags | QtCore.Qt.ItemIsDragEnabled | QtCore.Qt.ItemIsDropEnabled | QtCore.Qt.ItemIsEditable
|
|
99
|
+
|
|
100
|
+
def canDropMimeData(self, data, action, row, column, parent):
|
|
101
|
+
if parent.isValid():
|
|
102
|
+
pass
|
|
103
|
+
else:
|
|
104
|
+
return bool(self.node._onDropped)
|
|
105
|
+
|
|
106
|
+
def dropMimeData(self, data, action, row, column, parent):
|
|
107
|
+
if parent.isValid():
|
|
108
|
+
pass
|
|
109
|
+
else:
|
|
110
|
+
event = QtGui.QDropEvent(QtCore.QPoint(0,0), action, data, QtCore.Qt.MouseButton.LeftButton, QtCore.Qt.KeyboardModifier.NoModifier, QtCore.QEvent.Drop)
|
|
111
|
+
self.node._onDropped[0](event, *self.node._onDropped[1], **self.node._onDropped[2])
|
|
112
|
+
|
|
113
|
+
def parent(self, index):
|
|
114
|
+
if not index.isValid():
|
|
115
|
+
return QModelIndex()
|
|
116
|
+
node = index.internalPointer()
|
|
117
|
+
parent_node = node.parent
|
|
118
|
+
if parent_node:
|
|
119
|
+
return self.createIndex(0, 0, parent_node)
|
|
120
|
+
return QModelIndex()
|
|
121
|
+
|
|
122
|
+
def data(self, index, role):
|
|
123
|
+
if not index.isValid():
|
|
124
|
+
return None
|
|
125
|
+
node = index.internalPointer()
|
|
126
|
+
if role == QtCore.Qt.DisplayRole:
|
|
127
|
+
return node.data
|
|
128
|
+
return None
|
|
129
|
+
|
|
130
|
+
def rowCount(self, parent):
|
|
131
|
+
parent_node = parent.internalPointer() if parent.isValid() else self.rootnode
|
|
132
|
+
return len(parent_node.children)
|
|
133
|
+
|
|
134
|
+
def columnCount(self, parent):
|
|
135
|
+
return 1
|
|
136
|
+
|
|
137
|
+
def hasChildren(self, parent):
|
|
138
|
+
parent_node = parent.internalPointer() if parent.isValid() else self.rootnode
|
|
139
|
+
return len(parent_node.children) > 0
|
|
140
|
+
|
|
141
|
+
def clicked(self, node):
|
|
142
|
+
node._clicked(None)
|
|
143
|
+
|
|
144
|
+
def dblclicked(self, node):
|
|
145
|
+
node._dblclicked(None)
|
|
146
|
+
|
|
147
|
+
def expanded(self, node):
|
|
148
|
+
node._expanded()
|
|
149
|
+
|
|
150
|
+
def collapsed(self, node):
|
|
151
|
+
node._collapsed()
|
|
45
152
|
|
|
46
153
|
class Tree(QtBaseWidget):
|
|
47
|
-
def __init__(self, model):
|
|
154
|
+
def __init__(self, model=None):
|
|
48
155
|
super().__init__()
|
|
49
156
|
self.layout_weight = 1
|
|
50
157
|
self.model = model
|
|
@@ -66,11 +173,17 @@ class Tree(QtBaseWidget):
|
|
|
66
173
|
self.ui.expanded.connect(self.on_item_expanded)
|
|
67
174
|
self.ui.collapsed.connect(self.on_item_collapsed)
|
|
68
175
|
|
|
69
|
-
if self.
|
|
70
|
-
self.
|
|
71
|
-
|
|
176
|
+
if self.model:
|
|
177
|
+
if self.curr_model.set(self.model):
|
|
178
|
+
self.qt_model = QAbstractItemModelAdapter(self.model)
|
|
179
|
+
self.qt_model.node = self
|
|
180
|
+
self.ui.setModel(self.qt_model)
|
|
181
|
+
else:
|
|
182
|
+
self.qt_model.modelReset.emit()
|
|
72
183
|
else:
|
|
73
|
-
self.qt_model
|
|
184
|
+
self.qt_model = QTreeNodeModelAdapter(self)
|
|
185
|
+
self.qt_model.node = self
|
|
186
|
+
self.ui.setModel(self.qt_model)
|
|
74
187
|
|
|
75
188
|
for pending in self.pendings:
|
|
76
189
|
pending[0](*pending[1:])
|
|
@@ -99,22 +212,66 @@ class Tree(QtBaseWidget):
|
|
|
99
212
|
self.pendings.append([self.expandable, enabled])
|
|
100
213
|
return self
|
|
101
214
|
|
|
215
|
+
def expand(self, cb, *args, **kwargs):
|
|
216
|
+
self._expand_callback = (cb, args, kwargs)
|
|
217
|
+
return self
|
|
218
|
+
|
|
219
|
+
def _expanded(self):
|
|
220
|
+
if self._expand_callback:
|
|
221
|
+
cb, args, kwargs = self._expand_callback
|
|
222
|
+
cb(*args, **kwargs)
|
|
223
|
+
|
|
224
|
+
def collapse(self, cb, *args, **kwargs):
|
|
225
|
+
self._collapse_callback = (cb, args, kwargs)
|
|
226
|
+
return self
|
|
227
|
+
|
|
228
|
+
def _collapsed(self):
|
|
229
|
+
if self._collapse_callback:
|
|
230
|
+
cb, args, kwargs = self._collapse_callback
|
|
231
|
+
cb(*args, **kwargs)
|
|
232
|
+
|
|
102
233
|
def on_item_clicked(self, index):
|
|
103
234
|
node = self.get_node()
|
|
104
235
|
treenode = index.internalPointer()
|
|
105
|
-
|
|
236
|
+
self.qt_model.clicked(treenode)
|
|
106
237
|
|
|
107
238
|
def on_item_double_clicked(self, index):
|
|
108
239
|
node = self.get_node()
|
|
109
240
|
treenode = index.internalPointer()
|
|
110
|
-
|
|
241
|
+
self.qt_model.dblclicked(treenode)
|
|
111
242
|
|
|
112
243
|
def on_item_expanded(self, index):
|
|
113
244
|
node = self.get_node()
|
|
114
245
|
treenode = index.internalPointer()
|
|
115
|
-
|
|
246
|
+
self.qt_model.expanded(treenode)
|
|
116
247
|
|
|
117
248
|
def on_item_collapsed(self, index):
|
|
118
249
|
node = self.get_node()
|
|
119
250
|
treenode = index.internalPointer()
|
|
120
|
-
|
|
251
|
+
self.qt_model.collapsed(treenode)
|
|
252
|
+
|
|
253
|
+
class TreeNode(PUINode):
|
|
254
|
+
def __init__(self, data=""):
|
|
255
|
+
super().__init__()
|
|
256
|
+
self._set_callback = None
|
|
257
|
+
self.data = data
|
|
258
|
+
self._expand_callback = None
|
|
259
|
+
self._collapse_callback = None
|
|
260
|
+
|
|
261
|
+
def expand(self, cb, *args, **kwargs):
|
|
262
|
+
self._expand_callback = (cb, args, kwargs)
|
|
263
|
+
return self
|
|
264
|
+
|
|
265
|
+
def _expanded(self):
|
|
266
|
+
if self._expand_callback:
|
|
267
|
+
cb, args, kwargs = self._expand_callback
|
|
268
|
+
cb(*args, **kwargs)
|
|
269
|
+
|
|
270
|
+
def collapse(self, cb, *args, **kwargs):
|
|
271
|
+
self._collapse_callback = (cb, args, kwargs)
|
|
272
|
+
return self
|
|
273
|
+
|
|
274
|
+
def _collapsed(self):
|
|
275
|
+
if self._collapse_callback:
|
|
276
|
+
cb, args, kwargs = self._collapse_callback
|
|
277
|
+
cb(*args, **kwargs)
|
PUI/__init__.py
CHANGED
PUI/flet/textfield.py
CHANGED
|
@@ -32,10 +32,12 @@ class TextField(FBase):
|
|
|
32
32
|
|
|
33
33
|
def on_textbox_changed(self, e):
|
|
34
34
|
node = self.get_node()
|
|
35
|
-
node.editing = True
|
|
36
35
|
value = e.control.value
|
|
37
36
|
if node.edit_model:
|
|
37
|
+
node.editing = True
|
|
38
38
|
node.edit_model.value = value
|
|
39
|
+
else:
|
|
40
|
+
node.model.value = value
|
|
39
41
|
e = PUIEvent()
|
|
40
42
|
e.value = value
|
|
41
43
|
self._input(e)
|
PUI/node.py
CHANGED
|
@@ -73,6 +73,8 @@ class PUINode():
|
|
|
73
73
|
self._onMouseUp = None
|
|
74
74
|
self._onMouseMove = None
|
|
75
75
|
self._onWheel = None
|
|
76
|
+
self._onDragEntered = None
|
|
77
|
+
self._onDropped = None
|
|
76
78
|
|
|
77
79
|
self.ui = None
|
|
78
80
|
self.args = args
|
|
@@ -197,6 +199,8 @@ class PUINode():
|
|
|
197
199
|
node = self
|
|
198
200
|
while node.retired_by:
|
|
199
201
|
node = node.retired_by
|
|
202
|
+
if node is not self:
|
|
203
|
+
self.retired_by = node
|
|
200
204
|
return node
|
|
201
205
|
|
|
202
206
|
def __repr__(self):
|
|
@@ -304,6 +308,14 @@ class PUINode():
|
|
|
304
308
|
self.genKey()
|
|
305
309
|
return self
|
|
306
310
|
|
|
311
|
+
def dragEnter(self, callback, *cb_args, **cb_kwargs):
|
|
312
|
+
self._onDragEntered = callback, cb_args, cb_kwargs
|
|
313
|
+
return self
|
|
314
|
+
|
|
315
|
+
def drop(self, callback, *cb_args, **cb_kwargs):
|
|
316
|
+
self._onDropped = callback, cb_args, cb_kwargs
|
|
317
|
+
return self
|
|
318
|
+
|
|
307
319
|
def click(self, callback, *cb_args, **cb_kwargs):
|
|
308
320
|
self._onClicked = callback, cb_args, cb_kwargs
|
|
309
321
|
return self
|
PUI/state.py
CHANGED
|
@@ -8,7 +8,10 @@ class DummyBinding():
|
|
|
8
8
|
def __init__(self, value):
|
|
9
9
|
self.value = value
|
|
10
10
|
|
|
11
|
-
class
|
|
11
|
+
class BaseBinding():
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
class AttrBinding(BaseBinding):
|
|
12
15
|
def __init__(self, state, key):
|
|
13
16
|
try:
|
|
14
17
|
self.viewroot = find_puiview()
|
|
@@ -52,7 +55,7 @@ class AttrBinding():
|
|
|
52
55
|
listeners.update(l)
|
|
53
56
|
_notify(getattr(self.state, "_StateObject__pending"), listeners)
|
|
54
57
|
|
|
55
|
-
class ListBinding():
|
|
58
|
+
class ListBinding(BaseBinding):
|
|
56
59
|
def __init__(self, state, key):
|
|
57
60
|
try:
|
|
58
61
|
self.viewroot = find_puiview()
|
|
@@ -93,7 +96,7 @@ class ListBinding():
|
|
|
93
96
|
def emit(self):
|
|
94
97
|
_notify(getattr(self.state, "_StateList__pending"), getattr(self.state, "_StateList__listeners"))
|
|
95
98
|
|
|
96
|
-
class DictBinding():
|
|
99
|
+
class DictBinding(BaseBinding):
|
|
97
100
|
def __init__(self, state, key):
|
|
98
101
|
try:
|
|
99
102
|
self.viewroot = find_puiview()
|
PUI/textual/textfield.py
CHANGED
|
@@ -31,9 +31,11 @@ class TextField(TBase):
|
|
|
31
31
|
|
|
32
32
|
def _changed(self, value):
|
|
33
33
|
node = self.get_node()
|
|
34
|
-
node.editing = True
|
|
35
34
|
if node.edit_model:
|
|
36
|
-
|
|
35
|
+
node.editing = True
|
|
36
|
+
node.edit_model.value = value
|
|
37
|
+
else:
|
|
38
|
+
node.model.value = value
|
|
37
39
|
e = PUIEvent()
|
|
38
40
|
e.value = value
|
|
39
41
|
self._input(e)
|
PUI/tkinter/textfield.py
CHANGED
|
@@ -32,9 +32,11 @@ class TextField(TkBaseWidget):
|
|
|
32
32
|
|
|
33
33
|
def on_variable_changed(self, var, index, mode):
|
|
34
34
|
node = self.get_node()
|
|
35
|
-
node.editing = True
|
|
36
35
|
if node.edit_model:
|
|
36
|
+
node.editing = True
|
|
37
37
|
node.edit_model.value = self.variable.get()
|
|
38
|
+
else:
|
|
39
|
+
node.model.value = self.variable.get()
|
|
38
40
|
self._input()
|
|
39
41
|
|
|
40
42
|
def on_change(self):
|
PUI/wx/textfield.py
CHANGED
|
@@ -45,12 +45,13 @@ class TextField(WxBaseWidget):
|
|
|
45
45
|
|
|
46
46
|
def on_kill_focus(self, *args):
|
|
47
47
|
node = self.get_node()
|
|
48
|
-
node.editing = True
|
|
49
|
-
|
|
50
48
|
value = self.ui.GetValue()
|
|
51
49
|
node.model.value = value
|
|
52
50
|
if node.edit_model:
|
|
51
|
+
node.editing = True
|
|
53
52
|
node.edit_model.value = value
|
|
53
|
+
else:
|
|
54
|
+
node.model.value = value
|
|
54
55
|
e = PUIEvent()
|
|
55
56
|
e.value = value
|
|
56
57
|
self._change(e)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: qpuiq
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.12
|
|
4
4
|
Summary: "PUI" Python Declarative UI Framework
|
|
5
5
|
Home-page: https://github.com/buganini/PUI
|
|
6
6
|
Author: Buganini Chiu
|
|
@@ -17,8 +17,23 @@ PUI doesn't do UI itself, it turns imperative UI libraries into reactive/declara
|
|
|
17
17
|
[CPPUI: Experimental C++ Version](https://github.com/buganini/CPPUI)
|
|
18
18
|
|
|
19
19
|
# Installation
|
|
20
|
-
```
|
|
20
|
+
``` shell
|
|
21
21
|
pip install QPUIQ
|
|
22
|
+
|
|
23
|
+
# Optional, for hot-reload
|
|
24
|
+
pip install jurigged
|
|
25
|
+
|
|
26
|
+
# Optional, for PySide6 backend
|
|
27
|
+
pip install PySide6
|
|
28
|
+
|
|
29
|
+
# Optional, for textual backend
|
|
30
|
+
pip install textual
|
|
31
|
+
|
|
32
|
+
# Optional, for wxPython backend
|
|
33
|
+
pip install wxPython
|
|
34
|
+
|
|
35
|
+
# Optional, for flet backend
|
|
36
|
+
pip install flet
|
|
22
37
|
```
|
|
23
38
|
|
|
24
39
|
# Get Started
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
PUI/__init__.py,sha256=
|
|
1
|
+
PUI/__init__.py,sha256=XdqoyAVcheQeWKq1l0qpLMN6jfHigBEh9fskePCjnB8,966
|
|
2
2
|
PUI/common.py,sha256=iCMdJPgdKxnZObpjjYzxa_LN8eS4w0FOTfgaDwD_fGY,500
|
|
3
3
|
PUI/decorator.py,sha256=BN3POYv69QCDomoHENN-UA-d4wY_vfARIb5RJ2qEnS8,483
|
|
4
4
|
PUI/dom.py,sha256=RgdDyv6vSFgkCoj9G2cjzQQOiymG8DwmmSoAZfxYvJM,10141
|
|
5
5
|
PUI/interfaces.py,sha256=rGUciM3S6ICEVgVoahkva8yXUGpweqy1kAzhUQut40E,2182
|
|
6
|
-
PUI/node.py,sha256=
|
|
7
|
-
PUI/state.py,sha256=
|
|
6
|
+
PUI/node.py,sha256=lO0j4pCGLEkq226dD3NYNhUi0e7ect5_8aeWrEki6ZE,13245
|
|
7
|
+
PUI/state.py,sha256=BLz-LM_s4_T9Tu_AqombQc87gkV5N8Wgsq1njSkxkBY,20201
|
|
8
8
|
PUI/timeline.py,sha256=-mO1TLqxp2_3dk-EvdBE9wBkQf5RIPrPazTPXDzWSN0,940
|
|
9
9
|
PUI/utils.py,sha256=canb7_Uz0sQ1UZDzyDuIsfAVXzEfZCkc9F81sMY4rTE,505
|
|
10
10
|
PUI/view.py,sha256=Oe6sXLHD554GnlLlO5QpY7kegngkzrmMEYRHrdzGZUQ,4623
|
|
11
11
|
PUI/PySide6/__init__.py,sha256=z895ldBVUaEqfGQW4CvYhWh2F6L0qGQA1MXUHVMf9Ms,1110
|
|
12
12
|
PUI/PySide6/application.py,sha256=OsIE47efST4I13txD-7rS1cTWAGhynckl45Wdb1bafk,1471
|
|
13
|
-
PUI/PySide6/base.py,sha256=
|
|
13
|
+
PUI/PySide6/base.py,sha256=wAkvN_dxG8fKHUNH99lO2Kc9ZEENQFDkPt1hkDFSBLM,7910
|
|
14
14
|
PUI/PySide6/button.py,sha256=mHfcH98dABYgksuT58fK0amSwtCM9aaYwr7Y2EArEJA,561
|
|
15
15
|
PUI/PySide6/canvas.py,sha256=mkMjGXcQmUeV1a1HChv6KTWuh_5ao_qA-dYqCnsHo3s,9108
|
|
16
16
|
PUI/PySide6/checkbox.py,sha256=Rsns0BleE4g9yTDdlsD8IADU3qcQkVO2VsFVvYlNL88,900
|
|
@@ -29,11 +29,11 @@ PUI/PySide6/radiobutton.py,sha256=Qe5jjVkGSx8Pf3deAm-9c0cbYsrWl15W9UxrwrWuOo4,79
|
|
|
29
29
|
PUI/PySide6/scroll.py,sha256=T8eXTW5ABPWbyOV5ioKXbBNE1CdoPmQ9IRmb2x12tqI,5857
|
|
30
30
|
PUI/PySide6/splitter.py,sha256=ObjcC8UgkAL7o-xXhi4XIkDEKhC4s5Ukk7tKMNa023Q,797
|
|
31
31
|
PUI/PySide6/tab.py,sha256=tMkhEfD4Wb_7Hs4-u4nOzm87GSHqmehcnwcFm24qRIg,953
|
|
32
|
-
PUI/PySide6/table.py,sha256=
|
|
32
|
+
PUI/PySide6/table.py,sha256=TTCMf_YNKmkFiqs_qLqw3qbvFsxoBNnz9VMObx_2l3s,4800
|
|
33
33
|
PUI/PySide6/text.py,sha256=4kRRZiuH-bLLJMNZ6hK9zAWOorsG-l4uujHbG6I5S20,1069
|
|
34
|
-
PUI/PySide6/textfield.py,sha256=
|
|
34
|
+
PUI/PySide6/textfield.py,sha256=Us-UZMDCwrREwFLjPKKa3e3c_1U4WWD2kzFCe3xiY0k,2140
|
|
35
35
|
PUI/PySide6/toolbar.py,sha256=NPkn99D5xK4RLBA0vxLD7EqYu5eh9ucCL2y1vSJWQl4,1800
|
|
36
|
-
PUI/PySide6/tree.py,sha256=
|
|
36
|
+
PUI/PySide6/tree.py,sha256=G25bnOaKuI6rwyU745av8K6bH-Os0hMPcRxOqMoB47A,8915
|
|
37
37
|
PUI/PySide6/window.py,sha256=CpkIFpleVr3oXOM6vdukahWtX5SV6cWNc1TUW84JPM4,2694
|
|
38
38
|
PUI/flet/__init__.py,sha256=3YzGA0oPfu9eW8DtKQSoAsa8o6ZTGKWakYBTxGaaH8Y,438
|
|
39
39
|
PUI/flet/application.py,sha256=3ZGZrAngSEkVK-WseOV-n_6ljhd86ZKBgO6Jp2PmsJA,937
|
|
@@ -48,7 +48,7 @@ PUI/flet/radiobutton.py,sha256=IrgP_SvOImhZvFAZ6ZeAXv6KTUw3bEaGAIsxfODiO9I,830
|
|
|
48
48
|
PUI/flet/scroll.py,sha256=B2IKoE6yo5CB8BykH_wAh3hbEavTnboYtajdknpp3b4,2212
|
|
49
49
|
PUI/flet/tab.py,sha256=T26PZ-Ma_LPUx7u9qbxEnYqxuR1-qlytWiB9TDpu7G8,997
|
|
50
50
|
PUI/flet/text.py,sha256=HGnhOTDwG5pqceK8x_C6wCZj1AKuqZ9vEZB_NFwXZo4,1465
|
|
51
|
-
PUI/flet/textfield.py,sha256=
|
|
51
|
+
PUI/flet/textfield.py,sha256=7BPRrdf4pv8rDM5BpZzMQ9b456kZpXm81y7sVW3K4XM,1802
|
|
52
52
|
PUI/flet/window.py,sha256=NqUnGYvhk2Mpo_G2WthZOEvlU6VMx6AM-jWMKcUqGDM,650
|
|
53
53
|
PUI/textual/__init__.py,sha256=uj_j3Z3Jvt-OLG5WSuD8mQW3rqRlv5oi7pwxKfoGFfk,709
|
|
54
54
|
PUI/textual/application.py,sha256=FNpZ1j05EbE3XNxqMBDfsU_IPQ1k2Y7xw-5KLtwuFnI,2514
|
|
@@ -62,7 +62,7 @@ PUI/textual/radiobutton.py,sha256=zFKG2LeUnPXnxpxeW3cYqPwd91DQZWFUctundau-4b0,62
|
|
|
62
62
|
PUI/textual/scroll.py,sha256=QeMDXgIz-5fxcL4htM2pHJFD6RAsDiijgLO9PmhJOEA,2036
|
|
63
63
|
PUI/textual/tab.py,sha256=wcvyH1MZZNwwout8iJDifty_lqe6YuhfRpE3F0lUTBM,2158
|
|
64
64
|
PUI/textual/text.py,sha256=BHvgK3JqBU_LrnWbaaKBFxQ_50Z9lFhcdEJoVJqbcSc,782
|
|
65
|
-
PUI/textual/textfield.py,sha256=
|
|
65
|
+
PUI/textual/textfield.py,sha256=u01i-fhtSEMi_6F_bPWgf5TvRUQvuudaxi58Yp6WTbg,1412
|
|
66
66
|
PUI/textual/window.py,sha256=ygb1txNlo2bjQkKVzSD4UgU2OTzJ-zeEjM0p8wcYZJA,181
|
|
67
67
|
PUI/tkinter/__init__.py,sha256=VQjdak9UO-zI7n9Kr4q_B-kgCXgag2DVoWWP_QdH2uk,982
|
|
68
68
|
PUI/tkinter/application.py,sha256=NxWfU9NHJuceKMdLiGeklUKU5WjYVUomGL_hJpRtrbs,1141
|
|
@@ -77,7 +77,7 @@ PUI/tkinter/radiobutton.py,sha256=RBcC9u9v1N5RDTn6GxEwbJr0kYh43j-r7zB6Ic1pIqI,75
|
|
|
77
77
|
PUI/tkinter/scroll.py,sha256=MhBuGcKRlqiMiNG1I5bI_wCJT4rwLQbB4ViOsXHcdi8,6685
|
|
78
78
|
PUI/tkinter/tab.py,sha256=-1r95U0q3hnSLokD1QU3hsQ2wiDteZ6KZwula7rwbVQ,1426
|
|
79
79
|
PUI/tkinter/text.py,sha256=5IJOD86iodYqUD-lFnLUnD4vYvUw-8wUPoLNq_RuBsA,501
|
|
80
|
-
PUI/tkinter/textfield.py,sha256
|
|
80
|
+
PUI/tkinter/textfield.py,sha256=-jab7t5-wpIejINRftXczv0685cze-H7pm3lWigOT5w,1788
|
|
81
81
|
PUI/tkinter/window.py,sha256=IIieSxxanhGIvPy0krQuLrStsL_jTUdx6TKbEf64nyQ,1606
|
|
82
82
|
PUI/wx/__init__.py,sha256=j8L1kzL4CK_xeF0x5_NZekGETYP_1Dhq3-BuV1LtXoY,391
|
|
83
83
|
PUI/wx/application.py,sha256=Ku_mloCyiw-KTl8a09uTIhV7uupG_7urqw8jXIwQMLc,965
|
|
@@ -94,10 +94,10 @@ PUI/wx/progressbar.py,sha256=gj5j6f-zG78XW1mEIRqiOEYMoYjG16jzS44Vnh4i148,472
|
|
|
94
94
|
PUI/wx/radiobutton.py,sha256=x7WnCGXuNPV98MqF-tRLzMOOExim22rayNL8jAYVZWk,769
|
|
95
95
|
PUI/wx/scroll.py,sha256=LPwRL9KZuoKrTFEWo1_zW3l_Fbaznq_2jA9GuwTp8Dc,1199
|
|
96
96
|
PUI/wx/text.py,sha256=YeIyDyHH0xBcD_iXbYSTtvL25YDtug1QJNVPvCSAqEk,544
|
|
97
|
-
PUI/wx/textfield.py,sha256=
|
|
97
|
+
PUI/wx/textfield.py,sha256=BmMebfqlDJqacaKdh2SON88xF73l0csC7L7hoNjz-qs,1778
|
|
98
98
|
PUI/wx/window.py,sha256=juAsn3W4SzmH8f5LDGvjwppvPD8fDObRUJ_MkQFKCIE,1847
|
|
99
|
-
qpuiq-0.
|
|
100
|
-
qpuiq-0.
|
|
101
|
-
qpuiq-0.
|
|
102
|
-
qpuiq-0.
|
|
103
|
-
qpuiq-0.
|
|
99
|
+
qpuiq-0.12.dist-info/LICENSE.txt,sha256=1Xwik2AmLNGoIYhAPzvNC28M08Q3EvkOe4TtlQuSd_E,1072
|
|
100
|
+
qpuiq-0.12.dist-info/METADATA,sha256=0nqLbJxZZ-b2P_xn5Yu6DJTa3jTzNMTUaYIbcNCrjWs,5716
|
|
101
|
+
qpuiq-0.12.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
|
|
102
|
+
qpuiq-0.12.dist-info/top_level.txt,sha256=zMudhifPite0CEVGYvdi-5W3P_dpum71xjU7_g-ZHS0,4
|
|
103
|
+
qpuiq-0.12.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|