pyqttoolkit 0.9.1__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 (133) hide show
  1. pyqttoolkit/__init__.py +20 -0
  2. pyqttoolkit/_version.py +21 -0
  3. pyqttoolkit/application/__init__.py +18 -0
  4. pyqttoolkit/application/application.py +86 -0
  5. pyqttoolkit/application/garbage_collector.py +65 -0
  6. pyqttoolkit/colors/__init__.py +84 -0
  7. pyqttoolkit/config/__init__.py +20 -0
  8. pyqttoolkit/config/base.py +22 -0
  9. pyqttoolkit/config/composite.py +31 -0
  10. pyqttoolkit/config/default.py +27 -0
  11. pyqttoolkit/config/environment.py +35 -0
  12. pyqttoolkit/config/multi_json_file.py +93 -0
  13. pyqttoolkit/config/with_signal.py +30 -0
  14. pyqttoolkit/config/with_value_changed.py +31 -0
  15. pyqttoolkit/data/__init__.py +21 -0
  16. pyqttoolkit/data/bits.py +23 -0
  17. pyqttoolkit/data/cache.py +64 -0
  18. pyqttoolkit/data/interval.py +26 -0
  19. pyqttoolkit/data/message.py +29 -0
  20. pyqttoolkit/data/names.py +24 -0
  21. pyqttoolkit/datetime/__init__.py +16 -0
  22. pyqttoolkit/datetime/datetime.py +51 -0
  23. pyqttoolkit/datetime/qdatetime.py +53 -0
  24. pyqttoolkit/dependencies/__init__.py +56 -0
  25. pyqttoolkit/errors/__init__.py +19 -0
  26. pyqttoolkit/exceptions/__init__.py +18 -0
  27. pyqttoolkit/filesystem/__init__.py +24 -0
  28. pyqttoolkit/logs/__init__.py +140 -0
  29. pyqttoolkit/metadata/__init__.py +23 -0
  30. pyqttoolkit/metadata/dataframe_metadata_manager.py +105 -0
  31. pyqttoolkit/metadata/dict_metadata_manager.py +63 -0
  32. pyqttoolkit/metadata/id_generator.py +20 -0
  33. pyqttoolkit/metadata/metadata_manager_base.py +54 -0
  34. pyqttoolkit/models/__init__.py +26 -0
  35. pyqttoolkit/models/code_text.py +43 -0
  36. pyqttoolkit/models/dataframetable.py +135 -0
  37. pyqttoolkit/models/dictpropertytree.py +155 -0
  38. pyqttoolkit/models/dicttable.py +140 -0
  39. pyqttoolkit/models/json_text.py +52 -0
  40. pyqttoolkit/models/list_model.py +52 -0
  41. pyqttoolkit/models/module.py +26 -0
  42. pyqttoolkit/models/roles.py +23 -0
  43. pyqttoolkit/models/series_data.py +68 -0
  44. pyqttoolkit/models/span.py +36 -0
  45. pyqttoolkit/models/validation.py +27 -0
  46. pyqttoolkit/modules/__init__.py +18 -0
  47. pyqttoolkit/modules/events/__init__.py +19 -0
  48. pyqttoolkit/modules/events/add_signal.py +31 -0
  49. pyqttoolkit/modules/events/module_opening.py +21 -0
  50. pyqttoolkit/modules/events/rejectable.py +29 -0
  51. pyqttoolkit/modules/launcher_config.py +55 -0
  52. pyqttoolkit/modules/module.py +111 -0
  53. pyqttoolkit/properties/__init__.py +18 -0
  54. pyqttoolkit/properties/auto.py +221 -0
  55. pyqttoolkit/properties/throttled.py +77 -0
  56. pyqttoolkit/scripting/__init__.py +19 -0
  57. pyqttoolkit/scripting/script_context.py +36 -0
  58. pyqttoolkit/scripting/script_runner.py +132 -0
  59. pyqttoolkit/scripting/script_template.py +42 -0
  60. pyqttoolkit/services/__init__.py +32 -0
  61. pyqttoolkit/services/autosave.py +41 -0
  62. pyqttoolkit/services/email.py +25 -0
  63. pyqttoolkit/services/event_registry.py +52 -0
  64. pyqttoolkit/services/file_dialog.py +71 -0
  65. pyqttoolkit/services/hotkey_manager.py +137 -0
  66. pyqttoolkit/services/link_manager.py +135 -0
  67. pyqttoolkit/services/message_board.py +90 -0
  68. pyqttoolkit/services/module_service.py +154 -0
  69. pyqttoolkit/services/object_converter.py +45 -0
  70. pyqttoolkit/services/project_updater.py +149 -0
  71. pyqttoolkit/services/task_runner.py +281 -0
  72. pyqttoolkit/services/theme_manager.py +46 -0
  73. pyqttoolkit/services/tool_window_service.py +46 -0
  74. pyqttoolkit/viewmanagers/__init__.py +17 -0
  75. pyqttoolkit/viewmanagers/tool.py +23 -0
  76. pyqttoolkit/views/__init__.py +50 -0
  77. pyqttoolkit/views/bulk_value_selector.py +112 -0
  78. pyqttoolkit/views/check_box.py +36 -0
  79. pyqttoolkit/views/code/__init__.py +18 -0
  80. pyqttoolkit/views/code/code_edit.py +268 -0
  81. pyqttoolkit/views/code/python_syntax.py +226 -0
  82. pyqttoolkit/views/combo_box.py +101 -0
  83. pyqttoolkit/views/count_selector.py +59 -0
  84. pyqttoolkit/views/datetime.py +111 -0
  85. pyqttoolkit/views/datetime_range_selector.py +231 -0
  86. pyqttoolkit/views/default_text_line_edit.py +50 -0
  87. pyqttoolkit/views/delegates.py +117 -0
  88. pyqttoolkit/views/dtype_edit.py +117 -0
  89. pyqttoolkit/views/editable_combo_box.py +45 -0
  90. pyqttoolkit/views/file_selector.py +51 -0
  91. pyqttoolkit/views/icon.py +67 -0
  92. pyqttoolkit/views/icon_button.py +129 -0
  93. pyqttoolkit/views/json_edit.py +21 -0
  94. pyqttoolkit/views/labelled.py +29 -0
  95. pyqttoolkit/views/layout/__init__.py +21 -0
  96. pyqttoolkit/views/layout/collabsible.py +59 -0
  97. pyqttoolkit/views/layout/group_box.py +48 -0
  98. pyqttoolkit/views/layout/group_panel.py +188 -0
  99. pyqttoolkit/views/layout/lines.py +30 -0
  100. pyqttoolkit/views/layout/link.py +38 -0
  101. pyqttoolkit/views/line_edit.py +61 -0
  102. pyqttoolkit/views/linkable.py +49 -0
  103. pyqttoolkit/views/list_view.py +43 -0
  104. pyqttoolkit/views/main_window.py +91 -0
  105. pyqttoolkit/views/metadata_selector.py +84 -0
  106. pyqttoolkit/views/modulewindow.py +81 -0
  107. pyqttoolkit/views/plot/__init__.py +26 -0
  108. pyqttoolkit/views/plot/legend_control.py +121 -0
  109. pyqttoolkit/views/plot/matplotlib/__init__.py +23 -0
  110. pyqttoolkit/views/plot/matplotlib/base.py +1056 -0
  111. pyqttoolkit/views/plot/matplotlib/colorbar.py +75 -0
  112. pyqttoolkit/views/plot/matplotlib/colormap.py +48 -0
  113. pyqttoolkit/views/plot/matplotlib/font.py +55 -0
  114. pyqttoolkit/views/plot/plot_options.py +211 -0
  115. pyqttoolkit/views/plot/plot_toolbar_options.py +133 -0
  116. pyqttoolkit/views/plot/size.py +41 -0
  117. pyqttoolkit/views/plot/tool_type.py +26 -0
  118. pyqttoolkit/views/plot/toolbar.py +100 -0
  119. pyqttoolkit/views/popout.py +41 -0
  120. pyqttoolkit/views/popup.py +41 -0
  121. pyqttoolkit/views/property_tree.py +26 -0
  122. pyqttoolkit/views/shrunk_push_button.py +34 -0
  123. pyqttoolkit/views/steppable_combo_box.py +67 -0
  124. pyqttoolkit/views/styleable.py +37 -0
  125. pyqttoolkit/views/table.py +146 -0
  126. pyqttoolkit/views/text_edit.py +31 -0
  127. pyqttoolkit/views/tool_window.py +35 -0
  128. pyqttoolkit-0.9.1.dist-info/METADATA +69 -0
  129. pyqttoolkit-0.9.1.dist-info/RECORD +133 -0
  130. pyqttoolkit-0.9.1.dist-info/WHEEL +5 -0
  131. pyqttoolkit-0.9.1.dist-info/licenses/LICENSE.txt +674 -0
  132. pyqttoolkit-0.9.1.dist-info/licenses/LICENSE_SHORT +16 -0
  133. pyqttoolkit-0.9.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,188 @@
1
+ # pyqttoolkit
2
+ # Copyright (C) 2018-2019, Simmovation Ltd.
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software Foundation,
16
+ # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+ from PyQt5.QtCore import Qt
18
+ from PyQt5.QtWidgets import QBoxLayout, QWidget, QVBoxLayout, QLabel, QSizePolicy
19
+
20
+ from .lines import HLine, VLine
21
+ from .link import LinkWidget
22
+
23
+ class GroupPanelLayout(QBoxLayout):
24
+ def __init__(self, parent, direction):
25
+ super().__init__(direction, parent)
26
+ self._direction = direction
27
+ self._separator = VLine if not self.isVertical() else HLine
28
+ self._grid_layouts = []
29
+ self._containers = []
30
+ self._separators = []
31
+ self._layouts = []
32
+ self._labels = []
33
+ self._minimum_row_height = 0
34
+ self._spacing = 0
35
+ self._label_alignment = Qt.AlignCenter
36
+ self._panel_direction = QBoxLayout.TopToBottom
37
+ self._group_alignment = None
38
+
39
+ def addWidget(self, widget, group_name):
40
+ if self._containers:
41
+ self.addSeparator()
42
+ container = LinkWidget(self.parent(), widget)
43
+ layout = QVBoxLayout(container)
44
+ layout.setDirection(self._panel_direction)
45
+ layout.setContentsMargins(self._spacing, self._spacing, self._spacing, self._spacing)
46
+ self.addLabel(container, layout, group_name)
47
+ layout.addWidget(widget)
48
+ group_alignment = self._group_alignment if self._group_alignment is not None else Qt.Alignment(0)
49
+ self._containers.append(container)
50
+ self._layouts.append(layout)
51
+ super().addWidget(container, alignment=group_alignment)
52
+
53
+ def setLabelAlignment(self, alignment):
54
+ self._label_alignment = alignment
55
+
56
+ def setPanelDirection(self, direction):
57
+ self._panel_direction = direction
58
+
59
+ def setGroupAlignment(self, alignment):
60
+ self._group_alignment = alignment
61
+
62
+ def isVertical(self):
63
+ return self._direction in (QBoxLayout.TopToBottom, QBoxLayout.BottomToTop)
64
+
65
+ def addSeparator(self):
66
+ self._separators.append(self._separator(self.parent()))
67
+ super().addWidget(self._separators[-1])
68
+
69
+ def addLabel(self, parent, layout, name):
70
+ label = QLabel(name, parent)
71
+ label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
72
+ layout.addWidget(label, alignment=self._label_alignment)
73
+ self._labels.append(label)
74
+
75
+ def addStretch(self, stretch):
76
+ super().addStretch(stretch)
77
+
78
+ def setContentsMargins(self, left, top, right, bottom):
79
+ super().setContentsMargins(left, top, right, bottom)
80
+
81
+ def setSpacing(self, spacing):
82
+ self._spacing = spacing
83
+
84
+ def count(self):
85
+ return super().count()
86
+
87
+ def sizeHint(self):
88
+ return super().sizeHint()
89
+
90
+ def setGeometry(self, rect):
91
+ super().setGeometry(rect)
92
+
93
+ def itemAt(self, index):
94
+ return super().itemAt(index)
95
+
96
+ def takeAt(self, index):
97
+ return super().takeAt(index)
98
+
99
+ def minimumSize(self):
100
+ return super().minimumSize()
101
+
102
+ def hasHeightForWidth(self):
103
+ return super().hasHeightForWidth()
104
+
105
+ def heightForWidth(self, width):
106
+ return super().heightForWidth(width)
107
+
108
+ def update(self):
109
+ return super().update()
110
+
111
+ class HGroupPanelLayout(GroupPanelLayout):
112
+ def __init__(self, parent):
113
+ super().__init__(parent, QBoxLayout.LeftToRight)
114
+
115
+ class VGroupPanelLayout(GroupPanelLayout):
116
+ def __init__(self, parent):
117
+ super().__init__(parent, QBoxLayout.TopToBottom)
118
+
119
+ class GroupPanelWidget(QWidget):
120
+ def __init__(self, parent, direction):
121
+ super().__init__(parent)
122
+ self._layout = QBoxLayout(direction, self)
123
+ self._layout.setContentsMargins(0, 0, 0, 0)
124
+ self._direction = direction
125
+ self._separator = VLine if direction == QBoxLayout.LeftToRight else HLine
126
+ self._grid_layouts = []
127
+ self._containers = []
128
+ self._separators = []
129
+ self._layouts = []
130
+ self._labels = []
131
+ self._minimum_row_height = 0
132
+ self._spacing = 0
133
+ self._label_alignment = Qt.AlignCenter
134
+ self._panel_direction = QBoxLayout.TopToBottom
135
+ self._group_alignment = None
136
+
137
+ def addWidget(self, widget, group_name):
138
+ if self._containers:
139
+ self.addSeparator()
140
+ container = LinkWidget(self, widget)
141
+ layout = QVBoxLayout(container)
142
+ layout.setDirection(self._panel_direction)
143
+ layout.setContentsMargins(self._spacing, self._spacing, self._spacing, self._spacing)
144
+ self.addLabel(container, layout, group_name)
145
+ layout.addWidget(widget)
146
+ group_alignment = self._group_alignment if self._group_alignment is not None else Qt.Alignment(0)
147
+ self._containers.append(container)
148
+ self._layouts.append(layout)
149
+ self._layout.addWidget(container, alignment=group_alignment)
150
+
151
+ def setLabelAlignment(self, alignment):
152
+ self._label_alignment = alignment
153
+
154
+ def setPanelDirection(self, direction):
155
+ self._panel_direction = direction
156
+
157
+ def setGroupAlignment(self, alignment):
158
+ self._group_alignment = alignment
159
+
160
+ def isVertical(self):
161
+ return self._direction in (QBoxLayout.TopToBottom, QBoxLayout.BottomToTop)
162
+
163
+ def addSeparator(self):
164
+ self._separators.append(self._separator(self))
165
+ self._layout.addWidget(self._separators[-1])
166
+
167
+ def addLabel(self, parent, layout, name):
168
+ label = QLabel(name, parent)
169
+ label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
170
+ layout.addWidget(label, alignment=self._label_alignment)
171
+ self._labels.append(label)
172
+
173
+ def addStretch(self, stretch):
174
+ self._layout.addStretch(stretch)
175
+
176
+ def setContentsMargins(self, left, top, right, bottom):
177
+ self._layout.setContentsMargins(left, top, right, bottom)
178
+
179
+ def setSpacing(self, spacing):
180
+ self._spacing = spacing
181
+
182
+ class HGroupPanelWidget(GroupPanelWidget):
183
+ def __init__(self, parent):
184
+ super().__init__(parent, QBoxLayout.LeftToRight)
185
+
186
+ class VGroupPanelWidget(GroupPanelWidget):
187
+ def __init__(self, parent):
188
+ super().__init__(parent, QBoxLayout.TopToBottom)
@@ -0,0 +1,30 @@
1
+ # pyqttoolkit
2
+ # Copyright (C) 2018-2019, Simmovation Ltd.
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software Foundation,
16
+ # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+ from PyQt5.QtWidgets import QFrame
18
+
19
+ class HLine(QFrame):
20
+ def __init__(self, parent):
21
+ QFrame.__init__(self, parent)
22
+ self.setFrameShape(QFrame.HLine)
23
+ self.setFrameShadow(QFrame.Sunken)
24
+
25
+
26
+ class VLine(QFrame):
27
+ def __init__(self, parent):
28
+ QFrame.__init__(self, parent)
29
+ self.setFrameShape(QFrame.VLine)
30
+ self.setFrameShadow(QFrame.Sunken)
@@ -0,0 +1,38 @@
1
+ # pyqttoolkit
2
+ # Copyright (C) 2018-2019, Simmovation Ltd.
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software Foundation,
16
+ # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+ from PyQt5.QtWidgets import QWidget
18
+
19
+ class LinkWidget(QWidget):
20
+ def __init__(self, parent, linkable_widget):
21
+ super().__init__(parent)
22
+ self._linkable_widget = linkable_widget
23
+ if hasattr(self._linkable_widget, 'setLinkDisplay'):
24
+ self._linkable_widget.setLinkDisplay(self)
25
+
26
+ def mouseDoubleClickEvent(self, _event):
27
+ self.linkRequested()
28
+
29
+ def contextMenuEvent(self, event):
30
+ return self._linkable_widget.contextMenuEvent(event)
31
+
32
+ def setLinkDisplay(self, widget):
33
+ if hasattr(self._linkable_widget, 'setLinkDisplay'):
34
+ self._linkable_widget.setLinkDisplay(widget)
35
+
36
+ def linkRequested(self):
37
+ if hasattr(self._linkable_widget, 'linkRequested'):
38
+ self._linkable_widget.linkRequested()
@@ -0,0 +1,61 @@
1
+ # pyqttoolkit
2
+ # Copyright (C) 2018-2019, Simmovation Ltd.
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software Foundation,
16
+ # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+ from PyQt5.QtCore import pyqtSignal, Qt
18
+ from PyQt5.QtWidgets import QLineEdit
19
+
20
+ from pyqttoolkit.properties import AutoProperty
21
+ from pyqttoolkit.views.styleable import make_styleable
22
+
23
+ class LineEdit(QLineEdit):
24
+ def __init__(self, parent):
25
+ QLineEdit.__init__(self, parent)
26
+ self.focusLost.connect(self._on_edit_complete)
27
+ self.enterPressed.connect(self._on_edit_complete)
28
+
29
+ focusLost = pyqtSignal()
30
+ enterPressed = pyqtSignal()
31
+ editComplete = pyqtSignal(str)
32
+
33
+ def focusOutEvent(self, event):
34
+ self.focusLost.emit()
35
+ QLineEdit.focusOutEvent(self, event)
36
+
37
+ def keyPressEvent(self, event):
38
+ if event.key() in [Qt.Key_Enter, Qt.Key_Return]:
39
+ self.enterPressed.emit()
40
+ QLineEdit.keyPressEvent(self, event)
41
+
42
+ def _on_edit_complete(self):
43
+ self.editComplete.emit(self.text())
44
+
45
+ class BindableLineEdit(LineEdit):
46
+ def __init__(self, parent):
47
+ LineEdit.__init__(self, parent)
48
+ self.editComplete.connect(self._update_value)
49
+ self.valueChanged.connect(self._handle_value_changed)
50
+
51
+ valueChanged = pyqtSignal(str)
52
+
53
+ value = AutoProperty(str)
54
+
55
+ def _update_value(self, value):
56
+ self.value = value
57
+
58
+ def _handle_value_changed(self, value):
59
+ self.setText(value)
60
+
61
+ BindableLineEdit = make_styleable(BindableLineEdit)
@@ -0,0 +1,49 @@
1
+ # pyqttoolkit
2
+ # Copyright (C) 2018-2019, Simmovation Ltd.
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software Foundation,
16
+ # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+ from PyQt5.QtWidgets import QWidget
18
+
19
+ class LinkableWidget(QWidget):
20
+ def __init__(self, parent, link_manager=None, link_type=None):
21
+ QWidget.__init__(self, parent)
22
+ self._link_display = None
23
+ self._link_manager = link_manager
24
+ self._link_type = link_type
25
+
26
+ def linkDisplay(self):
27
+ return self._link_display or self
28
+
29
+ def setLinkDisplay(self, value):
30
+ self._link_display = value
31
+
32
+ def mouseDoubleClickEvent(self, _event):
33
+ self.linkRequested()
34
+
35
+ def linkRequested(self):
36
+ if self._link_manager is not None:
37
+ self._link_manager.request_link(self)
38
+
39
+ def link(self, other):
40
+ raise NotImplementedError()
41
+
42
+ def unlink(self, other):
43
+ raise NotImplementedError()
44
+
45
+ def linkType(self):
46
+ return self._link_type
47
+
48
+ def setLinkType(self, value):
49
+ self._link_type = value
@@ -0,0 +1,43 @@
1
+ # pyqttoolkit
2
+ # Copyright (C) 2018-2019, Simmovation Ltd.
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software Foundation,
16
+ # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+ from PyQt5.QtWidgets import QListView
18
+ from PyQt5.QtCore import pyqtSignal
19
+
20
+ from pyqttoolkit.properties import AutoProperty
21
+
22
+ class ListView(QListView):
23
+ def __init__(self, parent):
24
+ QListView.__init__(self, parent)
25
+ self.selectedIndexChanged.connect(self._handle_selected_index_changed)
26
+ self._updating_selection = False
27
+
28
+ selectedItemsChanged = pyqtSignal()
29
+ selectedIndexChanged = pyqtSignal(int)
30
+
31
+ selectedIndex = AutoProperty(int)
32
+
33
+ def selectionChanged(self, current_selection, previous_selection):
34
+ self._updating_selection = True
35
+ result = QListView.selectionChanged(self, current_selection, previous_selection)
36
+ self.selectedIndex = current_selection.indexes()[0].row() if current_selection.indexes() else -1
37
+ self.selectedItemsChanged.emit()
38
+ self._updating_selection = False
39
+ return result
40
+
41
+ def _handle_selected_index_changed(self, index):
42
+ if self.model() is not None and not self._updating_selection:
43
+ self.setCurrentIndex(self.model().createIndex(index, 0))
@@ -0,0 +1,91 @@
1
+ # pyqttoolkit
2
+ # Copyright (C) 2018-2019, Simmovation Ltd.
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software Foundation,
16
+ # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ from PyQt5.QtWidgets import QMainWindow, QStyleOption, QStyle
19
+ from PyQt5.QtGui import QPainter
20
+
21
+ from pyqttoolkit.colors import format_color
22
+
23
+ class MainWindow(QMainWindow):
24
+ def __init__(self, parent, theme_manager):
25
+ QMainWindow.__init__(self, parent)
26
+ self._theme_manager = theme_manager
27
+ self.setStyleSheet(self._get_stylesheet())
28
+ self._painter = None
29
+ self._opt = QStyleOption()
30
+
31
+ def paintEvent(self, _event):
32
+ self._opt.initFrom(self)
33
+ self._painter = QPainter(self)
34
+ self.style().drawPrimitive(QStyle.PE_Widget, self._opt, self._painter, self)
35
+ self._painter.end()
36
+ return super().paintEvent(_event)
37
+
38
+ @property
39
+ def themeManager(self):
40
+ return self._theme_manager
41
+
42
+ def _get_stylesheet(self):
43
+ color = lambda k: format_color(self._theme_manager.get_color(k))
44
+ color_a = lambda k, a: format_color(self._theme_manager.get_color(k), opacity=a)
45
+ return f"""
46
+ QMainWindow, QDialog {{
47
+ background-color: {color('module_background')};
48
+ }}
49
+
50
+ QLabel, QCheckBox, QGroupBox {{
51
+ color: {color('module_text')}
52
+ }}
53
+ QLabel:disabled, QCheckBox:disabled, QGroupBox:disabled, QPushButton:disabled {{
54
+ color: {color_a('module_text', 0.6)};
55
+ }}
56
+
57
+ QPushButton:disabled {{
58
+ background-color:#ccc;
59
+ border: 1px solid {color_a('module_text', 0.6)};
60
+ }}
61
+
62
+ QPushButton {{
63
+ color: #333;
64
+ border: 1px solid #555;
65
+ padding: 3px;
66
+ background: qradialgradient(cx: 0.3, cy: -0.4, fx: 0.3, fy: -0.4, radius: 1.35, stop: 0 #fff, stop: 1 #888);
67
+ }}
68
+
69
+ QPushButton[class=highlight] {{
70
+ color: #333;
71
+ border: 1px solid #555;
72
+ padding: 3px;
73
+ background: qradialgradient(cx: 0.3, cy: -0.4, fx: 0.3, fy: -0.4, radius: 1.35, stop: 0 #fff, stop: 1 {color('highlight')});
74
+ }}
75
+
76
+ QPushButton:hover {{
77
+ background: qradialgradient(cx: 0.3, cy: -0.4, fx: 0.3, fy: -0.4, radius: 1.35, stop: 0 #fff, stop: 1 #bbb);
78
+ }}
79
+
80
+ QPushButton:hover[class=highlight] {{
81
+ background: qradialgradient(cx: 0.3, cy: -0.4, fx: 0.3, fy: -0.4, radius: 1.35, stop: 0 #fff, stop: 1 {color('highlight_hover')});
82
+ }}
83
+
84
+ QPushButton:pressed {{
85
+ background: qradialgradient(cx: 0.4, cy: -0.1, fx: 0.4, fy: -0.1, radius: 1.35, stop: 0 #fff, stop: 1 #ddd);
86
+ }}
87
+
88
+ QPushButton:pressed[class=highlight] {{
89
+ background: qradialgradient(cx: 0.4, cy: -0.1, fx: 0.4, fy: -0.1, radius: 1.35, stop: 0 #fff, stop: 1 {color('highlight_pressed')});
90
+ }}
91
+ """
@@ -0,0 +1,84 @@
1
+ # pyqttoolkit
2
+ # Copyright (C) 2018-2019, Simmovation Ltd.
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software Foundation,
16
+ # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+ from PyQt5.QtWidgets import QWidget, QGridLayout, QSizePolicy, QHBoxLayout
18
+ from PyQt5.QtCore import pyqtSignal, QSize
19
+
20
+ from pyqttoolkit.models.roles import DataRole
21
+ from pyqttoolkit.views import ComboBox
22
+ from pyqttoolkit.properties import AutoProperty, bind
23
+ from .icon_button import IconButton
24
+
25
+ class MetadataSelectorDropDown(QWidget):
26
+ def __init__(self, parent):
27
+ QWidget.__init__(self, parent)
28
+
29
+ self._drop_down = ComboBox(self)
30
+ self._drop_down.currentIndexChanged.connect(self._update_current)
31
+
32
+ self._layout = QGridLayout(self)
33
+ self._layout.setContentsMargins(0, 0, 0, 0)
34
+ self._layout.addWidget(self._drop_down)
35
+
36
+ self.selectedIdChanged.connect(self._handle_selected_id_changed)
37
+ self.selectedId = None
38
+
39
+ selectedIdChanged = pyqtSignal(str)
40
+
41
+ selectedId = AutoProperty(str)
42
+
43
+ def setModel(self, model):
44
+ self._drop_down.setModel(model)
45
+ model.dataChanged.connect(self._handle_selected_id_changed)
46
+
47
+ def _update_current(self, index):
48
+ model_index = self._drop_down.model().createIndex(index, 0)
49
+ self.selectedId = self._drop_down.model().data(model_index, DataRole)
50
+
51
+ def _handle_selected_id_changed(self):
52
+ model = self._drop_down.model()
53
+ for i in range(model.rowCount()):
54
+ model_index = model.createIndex(i, 0)
55
+ if model.data(model_index, DataRole) == self.selectedId:
56
+ self._drop_down.setCurrentIndex(i)
57
+ return
58
+
59
+ class MetadataSelector(QWidget):
60
+ def __init__(self, parent):
61
+ QWidget.__init__(self, parent)
62
+
63
+ self._drop_down = MetadataSelectorDropDown(self)
64
+ self._drop_down.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
65
+ self._add_item = IconButton('plus.svg', self.tr('Add Item'), self, QSize(20, 20), 2)
66
+ self._add_item.clicked.connect(self.addItemSelected)
67
+
68
+ self._layout = QHBoxLayout(self)
69
+ self._layout.setContentsMargins(0, 0, 0, 0)
70
+ self._layout.addWidget(self._drop_down)
71
+ self._layout.addWidget(self._add_item)
72
+
73
+ bind(self, self._drop_down, 'selectedId')
74
+
75
+ selectedIdChanged = pyqtSignal(str)
76
+ addItemSelected = pyqtSignal()
77
+
78
+ selectedId = AutoProperty(str)
79
+
80
+ def setModel(self, model):
81
+ self._drop_down.setModel(model)
82
+
83
+ def setSelectorEnabled(self, enabled):
84
+ self._drop_down.setEnabled(enabled)
@@ -0,0 +1,81 @@
1
+ # pyqttoolkit
2
+ # Copyright (C) 2018-2019, Simmovation Ltd.
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software Foundation,
16
+ # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+ """:mod:`modulewindow`
18
+ Module window widget
19
+ """
20
+ from uuid import uuid4
21
+
22
+ from PyQt5.QtCore import pyqtSignal
23
+
24
+ from pyqttoolkit.modules.events import RejectableEvent
25
+
26
+ from .main_window import MainWindow
27
+
28
+ class ModuleWindow(MainWindow):
29
+ """class::ModuleWindow
30
+ Class for use with QWidget-based modules
31
+ """
32
+ def __init__(self, theme_manager, title=None, singleton: bool = False):
33
+ MainWindow.__init__(self, None, theme_manager)
34
+ self._id = uuid4()
35
+ self._theme_manager = theme_manager
36
+ self._singleton = singleton
37
+ self._force = not singleton
38
+ if title:
39
+ self.setWindowTitle(title)
40
+
41
+ closing = pyqtSignal(str)
42
+
43
+ def setModuleView(self, module_view):
44
+ """function::setModuleView(self, module_view)
45
+ Sets the module view (central widget)
46
+ """
47
+ self.setCentralWidget(module_view)
48
+
49
+ @property
50
+ def moduleId(self):
51
+ """function::id(self)
52
+ Returns the id for this module window
53
+ """
54
+ return str(self._id)
55
+
56
+ def closeEvent(self, event):
57
+ """function::closeEvent(self, event)
58
+ Decorates the base class with a closing event
59
+ """
60
+ if self._singleton and not self._force:
61
+ event.ignore()
62
+ self.hide()
63
+ return
64
+ if hasattr(self.centralWidget(), 'prepareClose'):
65
+ close_event = RejectableEvent()
66
+ self.centralWidget().prepareClose(close_event)
67
+ if not close_event.accepted:
68
+ event.ignore()
69
+ return
70
+ MainWindow.closeEvent(self, event)
71
+ if event.isAccepted():
72
+ self.centralWidget().close()
73
+ self.closing.emit(self.moduleId)
74
+
75
+ def forceClose(self):
76
+ self._force = True
77
+ return self.close()
78
+
79
+ @property
80
+ def themeManager(self):
81
+ return self._theme_manager