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/PySide6/scroll.py ADDED
@@ -0,0 +1,153 @@
1
+ from .. import *
2
+ from .base import *
3
+ from PySide6.QtWidgets import QSizePolicy
4
+ import math
5
+
6
+ class Scroll(QtBaseWidget):
7
+ pui_terminal = False
8
+ END = -0.0
9
+
10
+ def __init__(self, vertical=None, horizontal=False):
11
+ self.vertical = vertical
12
+ self.horizontal = horizontal
13
+ self.align_x = 0
14
+ self.align_y = 0
15
+ super().__init__()
16
+
17
+ def update(self, prev):
18
+ if prev and prev.ui:
19
+ self.ui = prev.ui
20
+ self.align_x = prev.align_x
21
+ self.align_y = prev.align_y
22
+ if prev.vsb_conn:
23
+ vsb = self.ui.verticalScrollBar()
24
+ vsb.valueChanged.disconnect(prev.vsb_conn)
25
+ vsb.rangeChanged.disconnect(prev.vsb_range_conn)
26
+ if prev.hsb_conn:
27
+ hsb = self.ui.horizontalScrollBar()
28
+ hsb.valueChanged.disconnect(prev.hsb_conn)
29
+ hsb.rangeChanged.disconnect(prev.hsb_range_conn)
30
+ else:
31
+ self.ui = QtWidgets.QScrollArea()
32
+ self.ui.setWidgetResizable(True)
33
+ if self.vertical is None:
34
+ self.ui.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAsNeeded)
35
+ elif self.vertical:
36
+ self.ui.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
37
+ else:
38
+ self.ui.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
39
+ if self.horizontal is None:
40
+ self.ui.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAsNeeded)
41
+ elif self.horizontal:
42
+ self.ui.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
43
+ else:
44
+ self.ui.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
45
+ vsb = self.ui.verticalScrollBar()
46
+ self.vsb_conn = vsb.valueChanged.connect(self.vsb_changed)
47
+ self.vsb_range_conn = vsb.rangeChanged.connect(self.vsb_range_changed)
48
+ hsb = self.ui.horizontalScrollBar()
49
+ self.hsb_conn = hsb.valueChanged.connect(self.hsb_changed)
50
+ self.hsb_range_conn = hsb.rangeChanged.connect(self.hsb_range_changed)
51
+ super().update(prev)
52
+
53
+ def addChild(self, idx, child):
54
+ if idx != 0:
55
+ return
56
+ if isinstance(child, QtBaseWidget) or isinstance(child, QtBaseLayout):
57
+ self.ui.setWidget(child.outer)
58
+ if not hasattr(child.outer, "origResizeEvent"):
59
+ child.outer.origResizeEvent = child.outer.resizeEvent
60
+ child.outer.setSizePolicy(QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Preferred))
61
+ child.outer.resizeEvent = self.onUiResized
62
+ elif child.children:
63
+ self.addChild(idx, child.children[0])
64
+
65
+ def removeChild(self, idx, child):
66
+ if idx != 0:
67
+ return
68
+ if isinstance(child, QtBaseWidget) or isinstance(child, QtBaseLayout):
69
+ child.outer.setParent(None)
70
+ elif child.children:
71
+ self.removeChild(idx, child.children[0])
72
+
73
+ def onUiResized(self, event):
74
+ node = self.get_node()
75
+ if node.destroyed:
76
+ return
77
+ node.children[0].outer.origResizeEvent(event)
78
+ node.children[0].outer.resizeEvent = self.onUiResized
79
+ if node.horizontal is False:
80
+ if isinstance(node.children[0], QtBaseLayout):
81
+ node.outer.setMinimumWidth(node.children[0].outer.sizeHint().width())
82
+ elif isinstance(node.children[0], QtBaseWidget):
83
+ node.outer.setMinimumWidth(node.children[0].outer.sizeHint().width())
84
+
85
+ if node.vertical is False:
86
+ if isinstance(node.children[0], QtBaseLayout):
87
+ node.outer.setMinimumHeight(node.children[0].outer.sizeHint().height())
88
+ elif isinstance(node.children[0], QtBaseWidget):
89
+ node.outer.setMinimumHeight(node.children[0].outer.sizeHint().height())
90
+
91
+ def scrollX(self, pos=0):
92
+ if math.copysign(1, pos) >= 0:
93
+ self.align_x = 0
94
+ self.hsb_offset = pos
95
+ else:
96
+ self.align_x = 1
97
+ self.hsb_offset = abs(pos)
98
+ return self
99
+
100
+ def scrollY(self, pos=0):
101
+ if math.copysign(1, pos) >= 0:
102
+ self.align_y = 0
103
+ self.vsb_offset = pos
104
+ else:
105
+ self.align_y = 1
106
+ self.vsb_offset = abs(pos)
107
+ return self
108
+
109
+ def hsb_changed(self, *args, **kwargs):
110
+ hsb = self.ui.horizontalScrollBar()
111
+ v = hsb.value()
112
+ if v < 10 and v > hsb.maximum() - 10:
113
+ pass
114
+ elif v < 10:
115
+ self.align_x = 0
116
+ elif v > hsb.maximum() - 10:
117
+ self.align_x = 1
118
+
119
+ def vsb_changed(self, *args, **kwargs):
120
+ vsb = self.ui.verticalScrollBar()
121
+ v = vsb.value()
122
+ if v < 10 and v > vsb.maximum() - 10:
123
+ pass
124
+ elif v < 10:
125
+ self.align_y = 0
126
+ elif v > vsb.maximum() - 10:
127
+ self.align_y = 1
128
+
129
+ def preSync(self):
130
+ hsb = self.ui.horizontalScrollBar()
131
+ if self.align_x == 0:
132
+ self.hsb_offset = hsb.value()
133
+ else:
134
+ self.hsb_offset = hsb.maximum() - hsb.value()
135
+ vsb = self.ui.verticalScrollBar()
136
+ if self.align_y == 0:
137
+ self.vsb_offset = vsb.value()
138
+ else:
139
+ self.vsb_offset = vsb.maximum() - vsb.value()
140
+
141
+ def vsb_range_changed(self, min, max):
142
+ vsb = self.ui.verticalScrollBar()
143
+ if self.align_y == 0:
144
+ vsb.setValue(self.vsb_offset)
145
+ else:
146
+ vsb.setValue(max - self.vsb_offset)
147
+
148
+ def hsb_range_changed(self, min, max):
149
+ hsb = self.ui.verticalScrollBar()
150
+ if self.align_y == 0:
151
+ hsb.setValue(self.hsb_offset)
152
+ else:
153
+ hsb.setValue(max - self.hsb_offset)
@@ -0,0 +1,25 @@
1
+ from .. import *
2
+ from .base import *
3
+
4
+ class Splitter(QtBaseWidget):
5
+ pui_terminal = False
6
+ def __init__(self, vertical=False):
7
+ super().__init__()
8
+ self.vertical = vertical
9
+
10
+ def update(self, prev):
11
+ if prev and prev.ui:
12
+ self.ui = prev.ui
13
+ else:
14
+ self.ui = QtWidgets.QSplitter()
15
+ self.ui.setOrientation(QtCore.Qt.Orientation.Vertical if self.vertical else QtCore.Qt.Orientation.Horizontal)
16
+ super().update(prev)
17
+
18
+ def addChild(self, idx, child):
19
+ if isinstance(child, QtBaseWidget) or isinstance(child, QtBaseLayout):
20
+ self.ui.insertWidget(idx, child.outer)
21
+ else:
22
+ self.addChild(idx, child.children[0])
23
+
24
+ def removeChild(self, idx, child):
25
+ child.outer.setParent(None)
PUI/PySide6/tab.py ADDED
@@ -0,0 +1,39 @@
1
+ from .. import *
2
+ from .base import *
3
+
4
+ class Tabs(QtBaseWidget):
5
+ NORTH = "n"
6
+ SOUTH = "s"
7
+ EAST = "e"
8
+ WEST = "w"
9
+ pui_terminal = False
10
+ def __init__(self, tabposition=NORTH):
11
+ super().__init__()
12
+ self.tabposition = tabposition
13
+
14
+ def update(self, prev):
15
+ if prev and prev.ui:
16
+ self.ui = prev.ui
17
+ else:
18
+ self.ui = QtWidgets.QTabWidget()
19
+ super().update(prev)
20
+
21
+ def addChild(self, idx, child):
22
+ parent = child.parent
23
+ while not isinstance(parent, Tab):
24
+ parent = parent.parent
25
+ self.ui.insertTab(idx, child.outer, parent.label)
26
+
27
+ def removeChild(self, idx, child):
28
+ self.ui.removeTab(idx)
29
+
30
+ def postSync(self):
31
+ for i,c in enumerate(self.children):
32
+ self.ui.setTabText(i, c.label)
33
+
34
+
35
+ class Tab(PUINode):
36
+ pui_virtual = True
37
+ def __init__(self, label):
38
+ super().__init__()
39
+ self.label = label
PUI/PySide6/table.py ADDED
@@ -0,0 +1,89 @@
1
+ from .. import *
2
+ from .base import *
3
+
4
+ class QtTableModelAdapter(QtCore.QAbstractTableModel):
5
+ def __init__(self, model: "BaseTableAdapter"):
6
+ super().__init__()
7
+ self.model = model
8
+
9
+ def data(self, index, role):
10
+ if role == QtCore.Qt.DisplayRole:
11
+ return self.model.data(index.row(), index.column())
12
+ elif role == QtCore.Qt.EditRole:
13
+ return self.model.editData(index.row(), index.column())
14
+
15
+ def setData(self, index, value, role):
16
+ if role == QtCore.Qt.EditRole:
17
+ self.model.setData(index.row(), index.column(), value)
18
+ return True
19
+
20
+ def flags(self, index):
21
+ flags = super().flags(index)
22
+ if self.model.editable(index.row(), index.column()):
23
+ flags |= QtCore.Qt.ItemIsEditable
24
+ return flags
25
+
26
+ def headerData(self, section, orientation, role):
27
+ if role == QtCore.Qt.DisplayRole:
28
+ if orientation == QtCore.Qt.Horizontal:
29
+ if hasattr(self.model, "columnHeader"):
30
+ if self.model.columnHeader is None:
31
+ return None
32
+ else:
33
+ return self.model.columnHeader(section)
34
+ else:
35
+ return super().headerData(section, orientation, role)
36
+ else:
37
+ if hasattr(self.model, "rowHeader"):
38
+ if self.model.rowHeader is None:
39
+ return None
40
+ else:
41
+ return self.model.rowHeader(section)
42
+ else:
43
+ return super().headerData(section, orientation, role)
44
+
45
+ def rowCount(self, index):
46
+ return self.model.rowCount()
47
+
48
+ def columnCount(self, index):
49
+ return self.model.columnCount()
50
+
51
+
52
+ class Table(QtBaseWidget):
53
+ def __init__(self, model, autofit=True):
54
+ super().__init__()
55
+ self.layout_weight = 1
56
+ self.model = model
57
+ self.autofit = autofit
58
+ self.curr_model = None
59
+
60
+ def update(self, prev):
61
+ if prev and prev.ui:
62
+ self.ui = prev.ui
63
+ self.qt_model = prev.qt_model
64
+ self.curr_model = prev.curr_model
65
+ else:
66
+ self.qt_model = None
67
+ self.curr_model = Prop()
68
+ self.ui = QtWidgets.QTableView()
69
+
70
+ if self.model.columnHeader is None:
71
+ self.ui.horizontalHeader().hide()
72
+ else:
73
+ self.ui.horizontalHeader().show()
74
+
75
+ if self.model.rowHeader is None:
76
+ self.ui.verticalHeader().hide()
77
+ else:
78
+ self.ui.verticalHeader().show()
79
+
80
+ if self.curr_model.set(self.model):
81
+ self.qt_model = QtTableModelAdapter(self.model)
82
+ self.ui.setModel(self.qt_model)
83
+ else:
84
+ self.qt_model.refresh()
85
+
86
+ if self.autofit:
87
+ self.ui.resizeColumnsToContents()
88
+
89
+ super().update(prev)
PUI/PySide6/text.py ADDED
@@ -0,0 +1,35 @@
1
+ from .. import *
2
+ from .base import *
3
+ from ..utils import *
4
+ from PySide6.QtWidgets import QSizePolicy
5
+
6
+ class Text(QtBaseWidget):
7
+ textformat = QtCore.Qt.TextFormat.PlainText
8
+ def __init__(self, text, selectable=False):
9
+ super().__init__()
10
+ self.text = str(text)
11
+ self.selectable = selectable
12
+
13
+ def update(self, prev):
14
+ if prev and prev.ui:
15
+ self.ui = prev.ui
16
+ self.ui.setText(self.text)
17
+ else:
18
+ self.ui = QtWidgets.QLabel(self.text)
19
+ self.ui.setTextFormat(self.textformat)
20
+ self.ui.setAlignment(QtCore.Qt.AlignmentFlag.AlignTop)
21
+ self.ui.setWordWrap(True)
22
+
23
+ if self.selectable:
24
+ self.ui.setTextInteractionFlags(QtCore.Qt.TextInteractionFlag.TextSelectableByMouse)
25
+ else:
26
+ self.ui.setTextInteractionFlags(QtCore.Qt.TextInteractionFlag.NoTextInteraction)
27
+
28
+ super().update(prev)
29
+
30
+
31
+ class Html(Text):
32
+ textformat = QtCore.Qt.TextFormat.RichText
33
+
34
+ class MarkDown(Text):
35
+ textformat = QtCore.Qt.TextFormat.MarkdownText
@@ -0,0 +1,62 @@
1
+ from .. import *
2
+ from .base import *
3
+
4
+ class TextField(QtBaseWidget):
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.ui = prev.ui
16
+ self.curr_value = prev.curr_value
17
+ self.ui.node = self
18
+ self.ui.textChanged.disconnect()
19
+ if self.curr_value.set(model_value) and not self.editing:
20
+ self.ui.setText(model_value)
21
+ self.ui.textChanged.connect(self.on_textchanged)
22
+ self.ui.editingFinished.disconnect()
23
+ self.ui.editingFinished.connect(self.on_editing_finished)
24
+ else:
25
+ self.ui = QtWidgets.QLineEdit()
26
+ self.ui.setFocusPolicy(QtCore.Qt.ClickFocus | QtCore.Qt.NoFocus)
27
+ self.ui.node = self
28
+ self.ui.setText(model_value)
29
+ self.curr_value = Prop(model_value)
30
+ self.ui.textChanged.connect(self.on_textchanged)
31
+ self.ui.editingFinished.connect(self.on_editing_finished)
32
+
33
+ if self.edit_model and not self.editing:
34
+ self.edit_model.value = model_value
35
+
36
+ super().update(prev)
37
+
38
+ def on_editing_finished(self):
39
+ node = self.get_node()
40
+ node.editing = False
41
+ value = self.ui.text()
42
+ node.model.value = value
43
+ if node.edit_model:
44
+ node.edit_model.value = value
45
+ model_value = str(self.model.value)
46
+ self.ui.blockSignals(True)
47
+ self.ui.setText(model_value)
48
+ self.ui.blockSignals(False)
49
+ e = PUIEvent()
50
+ e.value = value
51
+ self._change(e)
52
+ node.ui.clearFocus()
53
+
54
+ def on_textchanged(self):
55
+ node = self.get_node()
56
+ node.editing = True
57
+ value = self.ui.text()
58
+ if node.edit_model:
59
+ node.edit_model.value = value
60
+ e = PUIEvent()
61
+ e.value = value
62
+ self._input(e)
PUI/PySide6/toolbar.py ADDED
@@ -0,0 +1,57 @@
1
+ from .. import *
2
+ from .base import *
3
+
4
+ class ToolBar(PUINode):
5
+ pui_outoforder = True
6
+ def update(self, prev):
7
+ if prev and prev.ui:
8
+ self.ui = prev.ui
9
+ self.actions = prev.actions
10
+ else:
11
+ self.ui = QtWidgets.QToolBar()
12
+ self.actions = []
13
+
14
+ super().update(prev)
15
+
16
+ def addChild(self, idx, child):
17
+ if idx < len(self.actions):
18
+ if isinstance(child, ToolBarAction):
19
+ self.actions.insert(idx, self.ui.insertAction(self.actions[idx], child.outer))
20
+ else:
21
+ self.actions.insert(idx, self.ui.insertWidget(self.actions[idx], child.outer))
22
+ else:
23
+ if isinstance(child, ToolBarAction):
24
+ self.actions.append(self.ui.addAction(child.outer))
25
+ else:
26
+ self.actions.append(self.ui.addWidget(child.outer))
27
+
28
+ def removeChild(self, idx, child):
29
+ self.ui.removeAction(self.actions[idx])
30
+
31
+ class ToolBarAction(PUINode):
32
+ def __init__(self, text, icon=None):
33
+ super().__init__()
34
+ self.text = text
35
+ self.icon = icon
36
+ self.onTriggered = None
37
+
38
+ def update(self, prev):
39
+ if prev and prev.ui:
40
+ self.ui = prev.ui
41
+ self.ui.setText(self.text)
42
+ self.ui.triggered.disconnect()
43
+ else:
44
+ self.ui = QtGui.QAction(self.text)
45
+ if self.icon:
46
+ self.ui.setIcon(self.icon)
47
+ self.ui.triggered.connect(self._triggered)
48
+
49
+ super().update(prev)
50
+
51
+ def _triggered(self):
52
+ node = self.get_node()
53
+ if node.onTriggered:
54
+ node.onTriggered[0](*node.onTriggered[1], **node.onTriggered[2])
55
+
56
+ def trigger(self, callback, *cb_args, **cb_kwargs):
57
+ self.onTriggered = (callback, cb_args, cb_kwargs)
PUI/PySide6/tree.py ADDED
@@ -0,0 +1,120 @@
1
+ from .. import *
2
+ from .base import *
3
+ from PySide6.QtCore import Qt, QModelIndex, QAbstractItemModel
4
+
5
+ class QAbstractItemModelAdapter(QtCore.QAbstractItemModel):
6
+ def __init__(self, model: "BaseTreeAdapter"):
7
+ super().__init__()
8
+ self.model = model
9
+
10
+ def index(self, row, column, parent = QtCore.QModelIndex()):
11
+ parent_node = parent.internalPointer() if parent.isValid() else None
12
+ if 0 <= row and row < self.model.rowCount(parent_node):
13
+ child = self.model.child(parent_node, row)
14
+ return self.createIndex(row, column, child)
15
+ return QtCore.QModelIndex()
16
+
17
+ def parent(self, index):
18
+ if not index.isValid():
19
+ return QModelIndex()
20
+ node = index.internalPointer()
21
+ parent_node = self.model.parent(node)
22
+ if parent_node:
23
+ return self.createIndex(0, 0, parent_node)
24
+ return QModelIndex()
25
+
26
+ def data(self, index, role):
27
+ if not index.isValid():
28
+ return None
29
+ node = index.internalPointer()
30
+ if role == QtCore.Qt.DisplayRole:
31
+ return self.model.data(node)
32
+ return None
33
+
34
+ def rowCount(self, parent):
35
+ parent_node = parent.internalPointer() if parent.isValid() else None
36
+ return self.model.rowCount(parent_node)
37
+
38
+ def columnCount(self, parent):
39
+ return 1
40
+
41
+ def hasChildren(self, parent):
42
+ parent_node = parent.internalPointer() if parent.isValid() else None
43
+ return self.model.rowCount(parent_node) > 0
44
+
45
+
46
+ class Tree(QtBaseWidget):
47
+ def __init__(self, model):
48
+ super().__init__()
49
+ self.layout_weight = 1
50
+ self.model = model
51
+ self.curr_model = None
52
+ self.pendings = []
53
+
54
+ def update(self, prev):
55
+ if prev and prev.ui:
56
+ self.ui = prev.ui
57
+ self.qt_model = prev.qt_model
58
+ self.curr_model = prev.curr_model
59
+ else:
60
+ self.qt_model = None
61
+ self.curr_model = Prop()
62
+ self.ui = QtWidgets.QTreeView()
63
+ self.ui.setHeaderHidden(True)
64
+ self.ui.clicked.connect(self.on_item_clicked)
65
+ self.ui.doubleClicked.connect(self.on_item_double_clicked)
66
+ self.ui.expanded.connect(self.on_item_expanded)
67
+ self.ui.collapsed.connect(self.on_item_collapsed)
68
+
69
+ if self.curr_model.set(self.model):
70
+ self.qt_model = QAbstractItemModelAdapter(self.model)
71
+ self.ui.setModel(self.qt_model)
72
+ else:
73
+ self.qt_model.modelReset.emit()
74
+
75
+ for pending in self.pendings:
76
+ pending[0](*pending[1:])
77
+ self.pendings = []
78
+
79
+ super().update(prev)
80
+
81
+ def expandAll(self):
82
+ if self.ui:
83
+ self.ui.expandAll()
84
+ else:
85
+ self.pendings.append([self.expandAll])
86
+ return self
87
+
88
+ def collapseAll(self):
89
+ if self.ui:
90
+ self.ui.collapseAll()
91
+ else:
92
+ self.pendings.append([self.collapseAll])
93
+ return self
94
+
95
+ def expandable(self, enabled):
96
+ if self.ui:
97
+ self.ui.setItemsExpandable(enabled)
98
+ else:
99
+ self.pendings.append([self.expandable, enabled])
100
+ return self
101
+
102
+ def on_item_clicked(self, index):
103
+ node = self.get_node()
104
+ treenode = index.internalPointer()
105
+ node.model.clicked(treenode)
106
+
107
+ def on_item_double_clicked(self, index):
108
+ node = self.get_node()
109
+ treenode = index.internalPointer()
110
+ node.model.dblclicked(treenode)
111
+
112
+ def on_item_expanded(self, index):
113
+ node = self.get_node()
114
+ treenode = index.internalPointer()
115
+ node.model.expanded(treenode)
116
+
117
+ def on_item_collapsed(self, index):
118
+ node = self.get_node()
119
+ treenode = index.internalPointer()
120
+ node.model.collapsed(treenode)
PUI/PySide6/window.py ADDED
@@ -0,0 +1,81 @@
1
+ from .. import *
2
+ from .base import *
3
+ from .menu import *
4
+ from .modal import *
5
+ from .toolbar import *
6
+ from PySide6 import QtWidgets
7
+
8
+ class QMainWindow(QtWidgets.QMainWindow):
9
+ def keyPressEvent(self, event):
10
+ e = PUIEvent()
11
+ e.text = event.text()
12
+ self.node._keypress(e)
13
+
14
+ def mousePressEvent(self, event):
15
+ focused_widget = QtWidgets.QApplication.focusWidget()
16
+ if isinstance(focused_widget, QtWidgets.QLineEdit):
17
+ focused_widget.clearFocus()
18
+ super().mousePressEvent(event)
19
+
20
+ class Window(QtBaseWidget):
21
+ pui_terminal = False
22
+
23
+ def __init__(self, title=None, icon=None, size=None, maximize=None, fullscreen=None):
24
+ super().__init__()
25
+ self.title = title
26
+ if icon:
27
+ self.icon = QtGui.QIcon(icon)
28
+ else:
29
+ self.icon = None
30
+ self.size = size
31
+ self.maximize = maximize
32
+ self.fullscreen = fullscreen
33
+
34
+ def update(self, prev=None):
35
+ if prev and prev.ui:
36
+ self.ui = prev.ui
37
+ self.ui.node = self
38
+ self.curr_size = prev.curr_size
39
+ self.curr_maximize = prev.curr_maximize
40
+ self.curr_fullscreen = prev.curr_fullscreen
41
+ else:
42
+ self.ui = QMainWindow()
43
+ self.ui.node = self
44
+ self.ui.show()
45
+ self.curr_size = Prop()
46
+ self.curr_maximize = Prop()
47
+ self.curr_fullscreen = Prop()
48
+
49
+ if self.curr_size.set(self.size):
50
+ self.ui.resize(*self.size)
51
+ if self.curr_maximize.set(self.maximize):
52
+ self.ui.showMaximized()
53
+ if self.curr_fullscreen.set(self.fullscreen):
54
+ self.ui.showFullScreen()
55
+ if not self.title is None:
56
+ self.ui.setWindowTitle(self.title)
57
+ if not self.icon is None:
58
+ self.ui.setWindowIcon(self.icon)
59
+ super().update(prev)
60
+
61
+ def addChild(self, idx, child):
62
+ if isinstance(child, MenuBar):
63
+ self.ui.setMenuBar(child.outer)
64
+ elif isinstance(child, ToolBar):
65
+ self.ui.addToolBar(child.outer)
66
+ elif isinstance(child, Modal):
67
+ pass
68
+ elif isinstance(child, QtBaseWidget) or isinstance(child, QtBaseLayout):
69
+ self.ui.setCentralWidget(child.outer)
70
+ else:
71
+ self.addChild(idx, child.children[0])
72
+
73
+ def removeChild(self, idx, child):
74
+ if isinstance(child, MenuBar):
75
+ child.outer.close()
76
+ elif isinstance(child, Modal):
77
+ pass
78
+ elif isinstance(child, QtBaseWidget) or isinstance(child, QtBaseLayout):
79
+ child.outer.setParent(None)
80
+ else:
81
+ self.removeChild(idx, child.children[0])