py10x-universe 0.1.3__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.
- core_10x/__init__.py +42 -0
- core_10x/backbone/__init__.py +0 -0
- core_10x/backbone/backbone_store.py +59 -0
- core_10x/backbone/backbone_traitable.py +30 -0
- core_10x/backbone/backbone_user.py +66 -0
- core_10x/backbone/bound_data_domain.py +49 -0
- core_10x/backbone/namespace.py +101 -0
- core_10x/backbone/vault.py +38 -0
- core_10x/code_samples/__init__.py +0 -0
- core_10x/code_samples/_package_manifest.py +3 -0
- core_10x/code_samples/directories.py +181 -0
- core_10x/code_samples/person.py +76 -0
- core_10x/concrete_traits.py +356 -0
- core_10x/conftest.py +12 -0
- core_10x/curve.py +321 -0
- core_10x/data_domain.py +48 -0
- core_10x/data_domain_binder.py +45 -0
- core_10x/directory.py +250 -0
- core_10x/entity.py +8 -0
- core_10x/entity_filter.py +5 -0
- core_10x/environment_variables.py +147 -0
- core_10x/exec_control.py +84 -0
- core_10x/experimental/__init__.py +0 -0
- core_10x/experimental/data_protocol_ex.py +34 -0
- core_10x/global_cache.py +121 -0
- core_10x/manual_tests/__init__.py +0 -0
- core_10x/manual_tests/calendar_test.py +35 -0
- core_10x/manual_tests/ctor_update_bug.py +58 -0
- core_10x/manual_tests/debug_graph_on.py +17 -0
- core_10x/manual_tests/debug_graphoff_inside_graph_on.py +28 -0
- core_10x/manual_tests/enum_bits_test.py +17 -0
- core_10x/manual_tests/env_vars_trivial_test.py +12 -0
- core_10x/manual_tests/existing_traitable.py +33 -0
- core_10x/manual_tests/k10x_test1.py +13 -0
- core_10x/manual_tests/named_constant_test.py +121 -0
- core_10x/manual_tests/nucleus_trivial_test.py +42 -0
- core_10x/manual_tests/polars_test.py +14 -0
- core_10x/manual_tests/py_class_test.py +4 -0
- core_10x/manual_tests/rc_test.py +42 -0
- core_10x/manual_tests/rdate_test.py +12 -0
- core_10x/manual_tests/reference_serialization_bug.py +19 -0
- core_10x/manual_tests/resource_trivial_test.py +10 -0
- core_10x/manual_tests/store_uri_test.py +6 -0
- core_10x/manual_tests/trait_definition_test.py +19 -0
- core_10x/manual_tests/trait_filter_test.py +15 -0
- core_10x/manual_tests/trait_flag_modification_test.py +42 -0
- core_10x/manual_tests/trait_modification_bug.py +26 -0
- core_10x/manual_tests/traitable_as_of_test.py +82 -0
- core_10x/manual_tests/traitable_heir_test.py +39 -0
- core_10x/manual_tests/traitable_history_test.py +41 -0
- core_10x/manual_tests/traitable_serialization_test.py +54 -0
- core_10x/manual_tests/traitable_trivial_test.py +71 -0
- core_10x/manual_tests/trivial_graph_test.py +16 -0
- core_10x/manual_tests/ts_class_association_test.py +64 -0
- core_10x/manual_tests/ts_trivial_test.py +35 -0
- core_10x/named_constant.py +425 -0
- core_10x/nucleus.py +81 -0
- core_10x/package_manifest.py +85 -0
- core_10x/package_refactoring.py +153 -0
- core_10x/py_class.py +431 -0
- core_10x/rc.py +155 -0
- core_10x/rdate.py +339 -0
- core_10x/resource.py +189 -0
- core_10x/roman_number.py +67 -0
- core_10x/testlib/__init__.py +0 -0
- core_10x/testlib/test_store.py +240 -0
- core_10x/testlib/traitable_history_tests.py +787 -0
- core_10x/testlib/ts_tests.py +280 -0
- core_10x/trait.py +377 -0
- core_10x/trait_definition.py +176 -0
- core_10x/trait_filter.py +205 -0
- core_10x/trait_method_error.py +36 -0
- core_10x/traitable.py +1082 -0
- core_10x/traitable_cli.py +153 -0
- core_10x/traitable_heir.py +33 -0
- core_10x/traitable_id.py +31 -0
- core_10x/ts_store.py +172 -0
- core_10x/ts_store_type.py +26 -0
- core_10x/ts_union.py +147 -0
- core_10x/ui_hint.py +153 -0
- core_10x/unit_tests/test_concrete_traits.py +156 -0
- core_10x/unit_tests/test_converters.py +51 -0
- core_10x/unit_tests/test_curve.py +157 -0
- core_10x/unit_tests/test_directory.py +54 -0
- core_10x/unit_tests/test_documentation.py +172 -0
- core_10x/unit_tests/test_environment_variables.py +15 -0
- core_10x/unit_tests/test_filters.py +239 -0
- core_10x/unit_tests/test_graph.py +348 -0
- core_10x/unit_tests/test_named_constant.py +98 -0
- core_10x/unit_tests/test_rc.py +11 -0
- core_10x/unit_tests/test_rdate.py +484 -0
- core_10x/unit_tests/test_trait_method_error.py +80 -0
- core_10x/unit_tests/test_trait_modification.py +19 -0
- core_10x/unit_tests/test_traitable.py +959 -0
- core_10x/unit_tests/test_traitable_history.py +1 -0
- core_10x/unit_tests/test_ts_store.py +1 -0
- core_10x/unit_tests/test_ts_union.py +369 -0
- core_10x/unit_tests/test_ui_nodes.py +81 -0
- core_10x/unit_tests/test_xxcalendar.py +471 -0
- core_10x/vault/__init__.py +0 -0
- core_10x/vault/sec_keys.py +133 -0
- core_10x/vault/security_keys_old.py +168 -0
- core_10x/vault/vault.py +56 -0
- core_10x/vault/vault_traitable.py +56 -0
- core_10x/vault/vault_user.py +70 -0
- core_10x/xdate_time.py +136 -0
- core_10x/xnone.py +71 -0
- core_10x/xxcalendar.py +228 -0
- infra_10x/__init__.py +0 -0
- infra_10x/manual_tests/__init__.py +0 -0
- infra_10x/manual_tests/test_misc.py +16 -0
- infra_10x/manual_tests/test_prepare_filter_and_pipeline.py +25 -0
- infra_10x/mongodb_admin.py +111 -0
- infra_10x/mongodb_store.py +346 -0
- infra_10x/mongodb_utils.py +129 -0
- infra_10x/unit_tests/conftest.py +13 -0
- infra_10x/unit_tests/test_mongo_db.py +36 -0
- infra_10x/unit_tests/test_mongo_history.py +1 -0
- py10x_universe-0.1.3.dist-info/METADATA +406 -0
- py10x_universe-0.1.3.dist-info/RECORD +214 -0
- py10x_universe-0.1.3.dist-info/WHEEL +4 -0
- py10x_universe-0.1.3.dist-info/licenses/LICENSE +21 -0
- ui_10x/__init__.py +0 -0
- ui_10x/apps/__init__.py +0 -0
- ui_10x/apps/collection_editor_app.py +100 -0
- ui_10x/choice.py +212 -0
- ui_10x/collection_editor.py +135 -0
- ui_10x/concrete_trait_widgets.py +220 -0
- ui_10x/conftest.py +8 -0
- ui_10x/entity_stocker.py +173 -0
- ui_10x/examples/__init__.py +0 -0
- ui_10x/examples/_guess_word_data.py +14076 -0
- ui_10x/examples/collection_editor.py +17 -0
- ui_10x/examples/date_selector.py +14 -0
- ui_10x/examples/entity_stocker.py +18 -0
- ui_10x/examples/guess_word.py +392 -0
- ui_10x/examples/message_box.py +20 -0
- ui_10x/examples/multi_choice.py +17 -0
- ui_10x/examples/py_data_browser.py +66 -0
- ui_10x/examples/radiobox.py +29 -0
- ui_10x/examples/single_choice.py +31 -0
- ui_10x/examples/style_sheet.py +47 -0
- ui_10x/examples/trivial_entity_editor.py +18 -0
- ui_10x/platform.py +20 -0
- ui_10x/platform_interface.py +517 -0
- ui_10x/py_data_browser.py +249 -0
- ui_10x/qt6/__init__.py +0 -0
- ui_10x/qt6/conftest.py +8 -0
- ui_10x/qt6/manual_tests/__init__.py +0 -0
- ui_10x/qt6/manual_tests/basic_test.py +35 -0
- ui_10x/qt6/platform_implementation.py +275 -0
- ui_10x/qt6/utils.py +665 -0
- ui_10x/rio/__init__.py +0 -0
- ui_10x/rio/apps/examples/examples/__init__.py +22 -0
- ui_10x/rio/apps/examples/examples/components/__init__.py +3 -0
- ui_10x/rio/apps/examples/examples/components/collection_editor.py +15 -0
- ui_10x/rio/apps/examples/examples/pages/collection_editor.py +21 -0
- ui_10x/rio/apps/examples/examples/pages/login_page.py +88 -0
- ui_10x/rio/apps/examples/examples/pages/style_sheet.py +21 -0
- ui_10x/rio/apps/examples/rio.toml +14 -0
- ui_10x/rio/component_builder.py +497 -0
- ui_10x/rio/components/__init__.py +9 -0
- ui_10x/rio/components/group_box.py +31 -0
- ui_10x/rio/components/labeled_checkbox.py +18 -0
- ui_10x/rio/components/line_edit.py +37 -0
- ui_10x/rio/components/radio_button.py +32 -0
- ui_10x/rio/components/separator.py +24 -0
- ui_10x/rio/components/splitter.py +121 -0
- ui_10x/rio/components/tree_view.py +75 -0
- ui_10x/rio/conftest.py +35 -0
- ui_10x/rio/internals/__init__.py +0 -0
- ui_10x/rio/internals/app.py +192 -0
- ui_10x/rio/manual_tests/__init__.py +0 -0
- ui_10x/rio/manual_tests/basic_test.py +24 -0
- ui_10x/rio/manual_tests/splitter.py +27 -0
- ui_10x/rio/platform_implementation.py +91 -0
- ui_10x/rio/style_sheet.py +53 -0
- ui_10x/rio/unit_tests/test_collection_editor.py +68 -0
- ui_10x/rio/unit_tests/test_internals.py +630 -0
- ui_10x/rio/unit_tests/test_style_sheet.py +37 -0
- ui_10x/rio/widgets/__init__.py +46 -0
- ui_10x/rio/widgets/application.py +109 -0
- ui_10x/rio/widgets/button.py +48 -0
- ui_10x/rio/widgets/button_group.py +60 -0
- ui_10x/rio/widgets/calendar.py +23 -0
- ui_10x/rio/widgets/checkbox.py +24 -0
- ui_10x/rio/widgets/dialog.py +137 -0
- ui_10x/rio/widgets/group_box.py +27 -0
- ui_10x/rio/widgets/layout.py +34 -0
- ui_10x/rio/widgets/line_edit.py +37 -0
- ui_10x/rio/widgets/list.py +105 -0
- ui_10x/rio/widgets/message_box.py +70 -0
- ui_10x/rio/widgets/scroll_area.py +31 -0
- ui_10x/rio/widgets/spacer.py +6 -0
- ui_10x/rio/widgets/splitter.py +45 -0
- ui_10x/rio/widgets/text_edit.py +28 -0
- ui_10x/rio/widgets/tree.py +89 -0
- ui_10x/rio/widgets/unit_tests/test_button.py +101 -0
- ui_10x/rio/widgets/unit_tests/test_button_group.py +33 -0
- ui_10x/rio/widgets/unit_tests/test_calendar.py +114 -0
- ui_10x/rio/widgets/unit_tests/test_checkbox.py +109 -0
- ui_10x/rio/widgets/unit_tests/test_group_box.py +158 -0
- ui_10x/rio/widgets/unit_tests/test_label.py +43 -0
- ui_10x/rio/widgets/unit_tests/test_line_edit.py +140 -0
- ui_10x/rio/widgets/unit_tests/test_list.py +146 -0
- ui_10x/table_header_view.py +305 -0
- ui_10x/table_view.py +174 -0
- ui_10x/trait_editor.py +189 -0
- ui_10x/trait_widget.py +131 -0
- ui_10x/traitable_editor.py +200 -0
- ui_10x/traitable_view.py +131 -0
- ui_10x/unit_tests/conftest.py +8 -0
- ui_10x/unit_tests/test_platform.py +9 -0
- ui_10x/utils.py +661 -0
ui_10x/qt6/utils.py
ADDED
|
@@ -0,0 +1,665 @@
|
|
|
1
|
+
#TODO: delete this file, it is duplicated in ui_10x.utils
|
|
2
|
+
assert False, "use ui_10x.utils"
|
|
3
|
+
# from datetime import date
|
|
4
|
+
# import inspect
|
|
5
|
+
# import platform
|
|
6
|
+
#
|
|
7
|
+
# from PyQt6.QtWidgets import QLabel, QWidget, QCalendarWidget, QMessageBox, QGroupBox, QButtonGroup, QRadioButton, QApplication
|
|
8
|
+
# from PyQt6.QtWidgets import QListWidget, QLineEdit, QTreeWidgetItem, QTreeWidget, QSizePolicy
|
|
9
|
+
# from PyQt6.QtWidgets import QFrame, QVBoxLayout, QHBoxLayout, QSplitter, QDialog, QScrollArea, QPushButton, QStyle
|
|
10
|
+
# from PyQt6.QtCore import Qt, QObject, QThread, pyqtSignal, QBuffer, QIODevice #, QByteArray
|
|
11
|
+
# from PyQt6.QtGui import QColor, QGuiApplication, QPixmap
|
|
12
|
+
#
|
|
13
|
+
# # from asu.nx.directory import Directory
|
|
14
|
+
#
|
|
15
|
+
# from core_10x.named_constant import NamedConstant
|
|
16
|
+
# from core_10x.rc import RC
|
|
17
|
+
# from core_10x.global_cache import cache, singleton
|
|
18
|
+
#
|
|
19
|
+
# class UxAsync(QObject):
|
|
20
|
+
# SIGNAL = pyqtSignal()
|
|
21
|
+
# s_instances = {}
|
|
22
|
+
#
|
|
23
|
+
# @classmethod
|
|
24
|
+
# def _check_thread(cls, bound_method):
|
|
25
|
+
# if QThread.currentThread() != QGuiApplication.instance().thread():
|
|
26
|
+
# raise RuntimeError(f'You must have called UxAsync.init({bound_method.__name__}) in the UI thread')
|
|
27
|
+
#
|
|
28
|
+
# @classmethod
|
|
29
|
+
# def init(cls, bound_method):
|
|
30
|
+
# instance = cls.s_instances.get(bound_method)
|
|
31
|
+
# if not instance:
|
|
32
|
+
# cls._check_thread(bound_method)
|
|
33
|
+
# instance = cls()
|
|
34
|
+
# cls.s_instances[bound_method] = instance
|
|
35
|
+
#
|
|
36
|
+
# instance.SIGNAL.connect(bound_method, type = Qt.ConnectionType.QueuedConnection)
|
|
37
|
+
#
|
|
38
|
+
# return instance
|
|
39
|
+
#
|
|
40
|
+
# @classmethod
|
|
41
|
+
# def call(cls, bound_method):
|
|
42
|
+
# instance = cls.init(bound_method)
|
|
43
|
+
# instance.SIGNAL.emit()
|
|
44
|
+
#
|
|
45
|
+
# class UxRadioBox(QGroupBox):
|
|
46
|
+
# def __init__(self, named_constant_class, title = '', horizontal = False, default_value: NamedConstant = None):
|
|
47
|
+
# assert inspect.isclass(named_constant_class) and issubclass(named_constant_class, NamedConstant), 'subclass of NamedConstant is expected'
|
|
48
|
+
#
|
|
49
|
+
# self.nm_class = named_constant_class
|
|
50
|
+
# self.values = values = list(named_constant_class.s_dir.values())
|
|
51
|
+
#
|
|
52
|
+
# if default_value is None:
|
|
53
|
+
# default = 0
|
|
54
|
+
# else:
|
|
55
|
+
# assert isinstance(default_value, named_constant_class), f'{named_constant_class} - unknown default_values = {default_value}'
|
|
56
|
+
# for i, c_def in enumerate(values):
|
|
57
|
+
# if c_def is default_value:
|
|
58
|
+
# default = i
|
|
59
|
+
# break
|
|
60
|
+
# else:
|
|
61
|
+
# assert False, f'{default_value} is not found'
|
|
62
|
+
#
|
|
63
|
+
# if title:
|
|
64
|
+
# super().__init__(title)
|
|
65
|
+
# else:
|
|
66
|
+
# super().__init__()
|
|
67
|
+
#
|
|
68
|
+
#
|
|
69
|
+
# lay = QHBoxLayout() if horizontal else QVBoxLayout()
|
|
70
|
+
# self.setLayout(lay)
|
|
71
|
+
#
|
|
72
|
+
# self.group = group = QButtonGroup()
|
|
73
|
+
# for i, c_def in enumerate(named_constant_class.s_dir.values()):
|
|
74
|
+
# rb = QRadioButton(c_def.label)
|
|
75
|
+
# lay.addWidget(rb)
|
|
76
|
+
# group.addButton(rb, id = i)
|
|
77
|
+
# group.button(default).setChecked(True)
|
|
78
|
+
#
|
|
79
|
+
# def choice(self):
|
|
80
|
+
# i = self.group.checkedId()
|
|
81
|
+
# return self.values[i]
|
|
82
|
+
#
|
|
83
|
+
# def uxSeparator(horizontal = True) -> QLabel:
|
|
84
|
+
# direction = QFrame.Shape.HLine if horizontal else QFrame.Shape.VLine
|
|
85
|
+
# sep = QLabel()
|
|
86
|
+
# sep.setFrameStyle(direction | QFrame.Shadow.Sunken)
|
|
87
|
+
# return sep
|
|
88
|
+
#
|
|
89
|
+
# def uxToClipboard(text: str, **kwargs):
|
|
90
|
+
# cp = QGuiApplication.clipboard()
|
|
91
|
+
# cp.setText(text)
|
|
92
|
+
#
|
|
93
|
+
# def uxFromClipboard(**kwargs) -> str:
|
|
94
|
+
# cp = QGuiApplication.clipboard()
|
|
95
|
+
# return cp.text()
|
|
96
|
+
#
|
|
97
|
+
# def uxSuccess(text: str, parent = None, title = ''):
|
|
98
|
+
# if not title:
|
|
99
|
+
# title = 'Success'
|
|
100
|
+
# if not parent:
|
|
101
|
+
# parent = None
|
|
102
|
+
# QMessageBox.information(parent, title, text)
|
|
103
|
+
#
|
|
104
|
+
# def uxWarning(text: str, parent = None, title = ''):
|
|
105
|
+
# if not title:
|
|
106
|
+
# title = 'Warning'
|
|
107
|
+
# if not parent:
|
|
108
|
+
# parent = None
|
|
109
|
+
# QMessageBox.warning(parent, title, text)
|
|
110
|
+
#
|
|
111
|
+
# def uxAnswer(question: str, parent = None, title = '') -> bool:
|
|
112
|
+
# if not title:
|
|
113
|
+
# title = 'Waiting for your answer...'
|
|
114
|
+
# if not parent:
|
|
115
|
+
# parent = None
|
|
116
|
+
# sb = QMessageBox.question(parent, title, question)
|
|
117
|
+
# return True if sb == QMessageBox.StandardButton.Yes else False
|
|
118
|
+
#
|
|
119
|
+
# def uxMultiChoiceAnswer(named_constant_class, parent = None, title = '', default_value: NamedConstant = None):
|
|
120
|
+
# if not title:
|
|
121
|
+
# title = 'Pick one of the choices below:'
|
|
122
|
+
#
|
|
123
|
+
# if not parent:
|
|
124
|
+
# parent = None
|
|
125
|
+
#
|
|
126
|
+
# box = UxRadioBox(named_constant_class, default_value = default_value)
|
|
127
|
+
# d = UxDialog(box, parent = parent, title = title, cancel = '')
|
|
128
|
+
# d.exec()
|
|
129
|
+
# return box.choice()
|
|
130
|
+
#
|
|
131
|
+
# def uxPushButton(label: str, callback = None, style_icon = None, flat = False):
|
|
132
|
+
# if style_icon:
|
|
133
|
+
# if isinstance(style_icon, str):
|
|
134
|
+
# style_icon = getattr(QStyle, 'SP_' + style_icon, None)
|
|
135
|
+
# assert style_icon, f"Unknown style_icon = '{style_icon}'"
|
|
136
|
+
#
|
|
137
|
+
# assert isinstance(style_icon, int), 'Currently only str or int are supported for style_icon'
|
|
138
|
+
#
|
|
139
|
+
# style = QApplication.style()
|
|
140
|
+
# icon = style.standardIcon(style_icon)
|
|
141
|
+
# button = QPushButton(icon, label)
|
|
142
|
+
# else:
|
|
143
|
+
# button = QPushButton(label)
|
|
144
|
+
#
|
|
145
|
+
# if callback:
|
|
146
|
+
# button.clicked.connect(callback)
|
|
147
|
+
#
|
|
148
|
+
# if flat:
|
|
149
|
+
# button.setFlat(True)
|
|
150
|
+
#
|
|
151
|
+
# return button
|
|
152
|
+
#
|
|
153
|
+
# class UxDialog(QDialog):
|
|
154
|
+
# def _createButton(self, ok: bool, button_spec) -> QPushButton:
|
|
155
|
+
# if not button_spec:
|
|
156
|
+
# return None
|
|
157
|
+
#
|
|
158
|
+
# if isinstance(button_spec, str):
|
|
159
|
+
# label = button_spec
|
|
160
|
+
# icon = ''
|
|
161
|
+
#
|
|
162
|
+
# elif isinstance(button_spec, tuple):
|
|
163
|
+
# try:
|
|
164
|
+
# label, icon = button_spec
|
|
165
|
+
# except Exception:
|
|
166
|
+
# return None
|
|
167
|
+
#
|
|
168
|
+
# else:
|
|
169
|
+
# return None
|
|
170
|
+
#
|
|
171
|
+
# cb = self.onOk if ok else self.onCancel
|
|
172
|
+
# return uxPushButton(label, callback = cb, style_icon = icon)
|
|
173
|
+
#
|
|
174
|
+
# def __init__(
|
|
175
|
+
# self,
|
|
176
|
+
# w: QWidget,
|
|
177
|
+
# parent: QWidget = None,
|
|
178
|
+
# title: str = None,
|
|
179
|
+
# ok = 'Ok',
|
|
180
|
+
# cancel = 'Cancel',
|
|
181
|
+
# accept_callback = None,
|
|
182
|
+
# cancel_callback = None,
|
|
183
|
+
# min_width = 0,
|
|
184
|
+
# min_height = 0,
|
|
185
|
+
# window_flags = None
|
|
186
|
+
# ):
|
|
187
|
+
# """
|
|
188
|
+
# :param w: a QWidget to show
|
|
189
|
+
# :param parent: parent widget, if any
|
|
190
|
+
# :param title: dialog title
|
|
191
|
+
# :param accept_callback: context.method, where: method( context ) -> RC
|
|
192
|
+
# :param ok, cancel: labels and corresponding roles for Ok and Cancel buttons. No button if empty
|
|
193
|
+
# """
|
|
194
|
+
# super().__init__( parent )
|
|
195
|
+
# if title:
|
|
196
|
+
# self.setWindowTitle( title )
|
|
197
|
+
#
|
|
198
|
+
# if window_flags is None:
|
|
199
|
+
# window_flags = Qt.WindowType.CustomizeWindowHint | Qt.WindowType.Window | Qt.WindowType.WindowTitleHint | Qt.WindowType.WindowCloseButtonHint
|
|
200
|
+
#
|
|
201
|
+
# self.setWindowFlags(window_flags)
|
|
202
|
+
# self.accept_callback = accept_callback
|
|
203
|
+
# self.cancel_callback = cancel_callback if cancel_callback else self.reject
|
|
204
|
+
#
|
|
205
|
+
# if ok:
|
|
206
|
+
# ok = self._createButton(True, ok)
|
|
207
|
+
# if cancel:
|
|
208
|
+
# cancel = self._createButton(False, cancel)
|
|
209
|
+
#
|
|
210
|
+
# lay = QVBoxLayout()
|
|
211
|
+
# self.setLayout(lay)
|
|
212
|
+
#
|
|
213
|
+
# lay.addWidget(w)
|
|
214
|
+
#
|
|
215
|
+
# self.w_message = QLabel()
|
|
216
|
+
# self.w_message.setStyleSheet('color: red;')
|
|
217
|
+
# lay.addWidget(self.w_message)
|
|
218
|
+
#
|
|
219
|
+
# if ok or cancel:
|
|
220
|
+
# lay.addWidget(uxSeparator())
|
|
221
|
+
#
|
|
222
|
+
# bar = QHBoxLayout()
|
|
223
|
+
# lay.addLayout(bar)
|
|
224
|
+
#
|
|
225
|
+
# bar.addWidget(QLabel(), stretch = 1)
|
|
226
|
+
# if ok:
|
|
227
|
+
# bar.addWidget(ok)
|
|
228
|
+
# if cancel:
|
|
229
|
+
# bar.addWidget(cancel)
|
|
230
|
+
#
|
|
231
|
+
# if min_width > 0:
|
|
232
|
+
# self.setMinimumWidth(min_width)
|
|
233
|
+
# if min_height > 0:
|
|
234
|
+
# self.setMinimumHeight(min_height)
|
|
235
|
+
#
|
|
236
|
+
# def onOk(self):
|
|
237
|
+
# if self.accept_callback:
|
|
238
|
+
# rc = self.accept_callback()
|
|
239
|
+
# if not rc:
|
|
240
|
+
# self.message(rc.err())
|
|
241
|
+
# return
|
|
242
|
+
#
|
|
243
|
+
# self.done(1)
|
|
244
|
+
#
|
|
245
|
+
# def onCancel(self):
|
|
246
|
+
# self.reject()
|
|
247
|
+
# self.done(0)
|
|
248
|
+
#
|
|
249
|
+
# def message(self, text: str):
|
|
250
|
+
# self.w_message.setText(text)
|
|
251
|
+
#
|
|
252
|
+
# def uxPickDate(title = 'Pick a Date', show_date: date = None, grid = True, default = None):
|
|
253
|
+
# cal = QCalendarWidget()
|
|
254
|
+
# cal.setGridVisible(bool(grid))
|
|
255
|
+
# if show_date:
|
|
256
|
+
# cal.setSelectedDate(show_date)
|
|
257
|
+
# dlg = UxDialog(cal, title = title)
|
|
258
|
+
# rc = dlg.exec()
|
|
259
|
+
#
|
|
260
|
+
# return cal.selectedDate().toPyDate() if rc else default
|
|
261
|
+
#
|
|
262
|
+
# class UxStyleSheet:
|
|
263
|
+
# @classmethod
|
|
264
|
+
# def dumps(cls, data: dict) -> str:
|
|
265
|
+
# return '\n'.join(f'{name}: {value};' for name, value in data.items())
|
|
266
|
+
#
|
|
267
|
+
# @classmethod
|
|
268
|
+
# def loads(cls, sheet: str) -> dict:
|
|
269
|
+
# res = {}
|
|
270
|
+
# pairs = sheet.split(';')
|
|
271
|
+
# for pair in pairs:
|
|
272
|
+
# pair = pair.strip()
|
|
273
|
+
# if pair:
|
|
274
|
+
# name_value = pair.split(':')
|
|
275
|
+
# if len(name_value) == 2:
|
|
276
|
+
# name = name_value[0].strip()
|
|
277
|
+
# value = name_value[1].strip()
|
|
278
|
+
# res[name] = value
|
|
279
|
+
#
|
|
280
|
+
# return res
|
|
281
|
+
#
|
|
282
|
+
# @classmethod
|
|
283
|
+
# def slice(cls, w: QWidget, *attr_names) -> list:
|
|
284
|
+
# data = cls.loads(w.styleSheet())
|
|
285
|
+
# return [ data.get(name) for name in attr_names ]
|
|
286
|
+
#
|
|
287
|
+
# @classmethod
|
|
288
|
+
# def update(cls, w: QWidget, sheet_update: str, replace = False):
|
|
289
|
+
# if not replace:
|
|
290
|
+
# sh = w.styleSheet()
|
|
291
|
+
# data = cls.loads(sh)
|
|
292
|
+
# update_data = cls.loads(sheet_update)
|
|
293
|
+
# data.update(update_data)
|
|
294
|
+
# new_sh = cls.dumps(data)
|
|
295
|
+
# else:
|
|
296
|
+
# new_sh = sheet_update
|
|
297
|
+
#
|
|
298
|
+
# w.setStyleSheet(new_sh)
|
|
299
|
+
#
|
|
300
|
+
# @classmethod
|
|
301
|
+
# def _color(cls, style_sheet: str, attr_name: str):
|
|
302
|
+
# data = cls.loads(style_sheet)
|
|
303
|
+
# str_color = data.get(attr_name)
|
|
304
|
+
# return QColor(str_color) if str_color else None
|
|
305
|
+
#
|
|
306
|
+
# @classmethod
|
|
307
|
+
# def fg_color(cls, style_sheet: str) -> QColor:
|
|
308
|
+
# return cls._color(style_sheet, 'color')
|
|
309
|
+
#
|
|
310
|
+
# @classmethod
|
|
311
|
+
# def bg_color(cls, style_sheet: str) -> QColor:
|
|
312
|
+
# return cls._color(style_sheet, 'background-color')
|
|
313
|
+
#
|
|
314
|
+
# @classmethod
|
|
315
|
+
# def color(cls, style_sheet: str, background = False) -> QColor:
|
|
316
|
+
# return cls.bg_color(style_sheet) if background else cls.fg_color(style_sheet)
|
|
317
|
+
#
|
|
318
|
+
# s_verticalAlignmentMap = {
|
|
319
|
+
# -1: Qt.AlignmentFlag.AlignTop,
|
|
320
|
+
# 0: Qt.AlignmentFlag.AlignVCenter,
|
|
321
|
+
# 1: Qt.AlignmentFlag.AlignBottom,
|
|
322
|
+
# }
|
|
323
|
+
# s_horizontalAlignmentMap = {
|
|
324
|
+
# -1: Qt.AlignmentFlag.AlignLeft,
|
|
325
|
+
# 0: Qt.AlignmentFlag.AlignCenter,
|
|
326
|
+
# 1: Qt.AlignmentFlag.AlignRight,
|
|
327
|
+
# }
|
|
328
|
+
# def uxTextAlignment(align_value: int, horizontal = True) -> int:
|
|
329
|
+
# if horizontal:
|
|
330
|
+
# return s_horizontalAlignmentMap.get(align_value, Qt.AlignmentFlag.AlignRight) | Qt.AlignmentFlag.AlignVCenter
|
|
331
|
+
#
|
|
332
|
+
# raise NotImplementedError
|
|
333
|
+
#
|
|
334
|
+
# class UX_SCROLL:
|
|
335
|
+
# OFF = Qt.ScrollBarPolicy.ScrollBarAlwaysOff
|
|
336
|
+
# ON = Qt.ScrollBarPolicy.ScrollBarAlwaysOn
|
|
337
|
+
# AS_NEEDED = Qt.ScrollBarPolicy.ScrollBarAsNeeded
|
|
338
|
+
#
|
|
339
|
+
# def uxMakeScrollable(w: QWidget, h = UX_SCROLL.AS_NEEDED, v = UX_SCROLL.AS_NEEDED) -> QWidget:
|
|
340
|
+
# if h is UX_SCROLL.OFF and v is UX_SCROLL.OFF:
|
|
341
|
+
# return w
|
|
342
|
+
#
|
|
343
|
+
# sa = QScrollArea()
|
|
344
|
+
# sa.setWidget(w)
|
|
345
|
+
# sa.setHorizontalScrollBarPolicy(h)
|
|
346
|
+
# sa.setVerticalScrollBarPolicy(v)
|
|
347
|
+
# return sa
|
|
348
|
+
#
|
|
349
|
+
# class UxSearchableList(QGroupBox):
|
|
350
|
+
# def __init__(
|
|
351
|
+
# self,
|
|
352
|
+
# text_widget: QLineEdit = None,
|
|
353
|
+
# reset_selection = True,
|
|
354
|
+
# choices: list = None,
|
|
355
|
+
# select_hook = None,
|
|
356
|
+
# sort = False,
|
|
357
|
+
# case_sensitive = False,
|
|
358
|
+
# title = ''
|
|
359
|
+
# ):
|
|
360
|
+
# """
|
|
361
|
+
# :param text_widget: if an external text_widget given, it is used, otherwise its own is created on top of the list
|
|
362
|
+
# :param reset_selection: if True, text_widget will be reset on new selection
|
|
363
|
+
# :param choices: all choices
|
|
364
|
+
# :param select_hook: if given, will be called after a new selection is made: select_hook( selected_choice: str )
|
|
365
|
+
# :param sort: sort choices if True
|
|
366
|
+
# :param case_sensitive: whether to search with case sensitivity
|
|
367
|
+
# :param title: an optional title
|
|
368
|
+
# """
|
|
369
|
+
# super().__init__()
|
|
370
|
+
# self.m_sort = sort
|
|
371
|
+
# self.m_initialChoices = choices if not sort else sorted( choices )
|
|
372
|
+
# self.m_currentChoices = self.m_initialChoices
|
|
373
|
+
# self.m_hook = select_hook
|
|
374
|
+
# self.m_resetSelection = reset_selection
|
|
375
|
+
# self.m_caseSensitive = case_sensitive
|
|
376
|
+
# self.m_choice = None
|
|
377
|
+
#
|
|
378
|
+
# if title:
|
|
379
|
+
# self.setTitle( title)
|
|
380
|
+
# lay = QVBoxLayout()
|
|
381
|
+
#
|
|
382
|
+
# if text_widget:
|
|
383
|
+
# self.m_field = text_widget
|
|
384
|
+
# else:
|
|
385
|
+
# self.m_field = QLineEdit()
|
|
386
|
+
# lay.addWidget( self.m_field )
|
|
387
|
+
# self.m_field.textEdited.connect( self.processInput )
|
|
388
|
+
#
|
|
389
|
+
# self.m_list = QListWidget()
|
|
390
|
+
#
|
|
391
|
+
# self.m_list.addItems( self.m_initialChoices )
|
|
392
|
+
# self.m_list.clicked.connect( self.itemSelected )
|
|
393
|
+
# lay.addWidget( self.m_list )
|
|
394
|
+
#
|
|
395
|
+
# self.setLayout( lay )
|
|
396
|
+
#
|
|
397
|
+
# def addChoice( self, choice: str ):
|
|
398
|
+
# if not choice in self.m_initialChoices:
|
|
399
|
+
# self.m_initialChoices.append( choice )
|
|
400
|
+
# if self.m_sort:
|
|
401
|
+
# self.m_initialChoices = sorted( self.m_initialChoices )
|
|
402
|
+
#
|
|
403
|
+
# self.m_list.clear()
|
|
404
|
+
# self.m_list.addItems( self.m_initialChoices )
|
|
405
|
+
#
|
|
406
|
+
# def removeChoice( self, choice: str ):
|
|
407
|
+
# if choice in self.m_initialChoices:
|
|
408
|
+
# self.m_initialChoices.remove( choice )
|
|
409
|
+
# self.m_list.clear()
|
|
410
|
+
# self.m_list.addItems( self.m_initialChoices )
|
|
411
|
+
#
|
|
412
|
+
# def processInput( self, input ):
|
|
413
|
+
# self.m_list.clear()
|
|
414
|
+
# if not input:
|
|
415
|
+
# self.m_currentChoices = self.m_initialChoices
|
|
416
|
+
# else:
|
|
417
|
+
# if not self.m_currentChoices:
|
|
418
|
+
# self.m_currentChoices = self.m_initialChoices
|
|
419
|
+
#
|
|
420
|
+
# if not self.m_caseSensitive:
|
|
421
|
+
# input = input.lower()
|
|
422
|
+
# self.m_currentChoices = [ s for s in self.m_currentChoices if not s.lower().find( input ) == -1 ]
|
|
423
|
+
# else:
|
|
424
|
+
# self.m_currentChoices = [ s for s in self.m_currentChoices if not s.find( input ) == -1 ]
|
|
425
|
+
#
|
|
426
|
+
# self.m_list.addItems( self.m_currentChoices )
|
|
427
|
+
#
|
|
428
|
+
# def itemSelected( self, item ):
|
|
429
|
+
# i = item.row()
|
|
430
|
+
# text = self.m_currentChoices[ i ]
|
|
431
|
+
# self.reset()
|
|
432
|
+
#
|
|
433
|
+
# items = self.m_list.findItems( text, Qt.MatchExactly )
|
|
434
|
+
# if len( items ):
|
|
435
|
+
# items[ 0 ].setSelected( True )
|
|
436
|
+
# text_s = '' if self.m_resetSelection else text
|
|
437
|
+
# self.m_field.setText( text_s )
|
|
438
|
+
#
|
|
439
|
+
# self.m_choice = text
|
|
440
|
+
# if self.m_hook:
|
|
441
|
+
# self.m_hook( text )
|
|
442
|
+
#
|
|
443
|
+
# def choice( self ) -> str:
|
|
444
|
+
# return self.m_choice
|
|
445
|
+
#
|
|
446
|
+
# def reset( self ):
|
|
447
|
+
# if not self.m_currentChoices == self.m_initialChoices:
|
|
448
|
+
# self.m_currentChoices = self.m_initialChoices
|
|
449
|
+
# self.m_list.clear()
|
|
450
|
+
# self.m_list.addItems( self.m_initialChoices )
|
|
451
|
+
#
|
|
452
|
+
# # class UxTreeViewer( QTreeWidget ):
|
|
453
|
+
# # s_labelMaxLength = 40
|
|
454
|
+
# #
|
|
455
|
+
# # def __init__( self, dir: Directory, select_hook = None, label_max_length = -1, expand = False, **kwargs ):
|
|
456
|
+
# # super().__init__()
|
|
457
|
+
# # if label_max_length < 0:
|
|
458
|
+
# # label_max_length = self.s_labelMaxLength
|
|
459
|
+
# #
|
|
460
|
+
# # self.m_dir = dir
|
|
461
|
+
# # self.m_selectHook = select_hook
|
|
462
|
+
# #
|
|
463
|
+
# # dir_value = dir.dir_value()
|
|
464
|
+
# # dir_name = dir.dir_name()
|
|
465
|
+
# # if dir_value and dir_name and dir_name != dir_value:
|
|
466
|
+
# # num_cols = 2
|
|
467
|
+
# # header_labels = [ dir.dir_name(), 'Description' ]
|
|
468
|
+
# # else:
|
|
469
|
+
# # num_cols = 1
|
|
470
|
+
# # header_labels = [ dir.show_value() ]
|
|
471
|
+
# #
|
|
472
|
+
# # self.m_numCols = num_cols
|
|
473
|
+
# # self.setColumnCount( num_cols )
|
|
474
|
+
# # self.setHeaderLabels( header_labels )
|
|
475
|
+
# # self.itemClicked.connect( self.typeTreeItemClicked )
|
|
476
|
+
# #
|
|
477
|
+
# # for subdir in dir.dir_members().values(): # -- without the root!
|
|
478
|
+
# # self.createTree( subdir, self, label_max_length, num_cols )
|
|
479
|
+
# #
|
|
480
|
+
# # if expand:
|
|
481
|
+
# # for i in range( self.topLevelItemCount() ):
|
|
482
|
+
# # top = self.topLevelItem( i )
|
|
483
|
+
# # top.setExpanded( True )
|
|
484
|
+
# #
|
|
485
|
+
# # self.resizeColumnToContents( 0 )
|
|
486
|
+
# # if num_cols == 2:
|
|
487
|
+
# # self.resizeColumnToContents( 1 )
|
|
488
|
+
# # self.setSizePolicy( QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding )
|
|
489
|
+
# #
|
|
490
|
+
# # class TreeItem( QTreeWidgetItem ):
|
|
491
|
+
# # def __init__( self, parent_node, dir: Directory ):
|
|
492
|
+
# # super().__init__( parent_node )
|
|
493
|
+
# # self.m_dir = dir
|
|
494
|
+
# #
|
|
495
|
+
# # def dir( self ): return self.m_dir
|
|
496
|
+
# #
|
|
497
|
+
# # @classmethod
|
|
498
|
+
# # def createTree( cls, dir: Directory, parent_node, label_max_length: int, num_cols: int ):
|
|
499
|
+
# # node = cls.TreeItem( parent_node, dir )
|
|
500
|
+
# # show_value = dir.show_value()
|
|
501
|
+
# # node.setText( 0, show_value )
|
|
502
|
+
# # if num_cols == 2:
|
|
503
|
+
# # label = dir.dir_name()
|
|
504
|
+
# # if label and label != show_value:
|
|
505
|
+
# # if len( label ) > label_max_length:
|
|
506
|
+
# # label = label[ :label_max_length ] + '...'
|
|
507
|
+
# #
|
|
508
|
+
# # node.setText( 1, label )
|
|
509
|
+
# #
|
|
510
|
+
# # node.setToolTip( num_cols - 1, dir.dir_name() )
|
|
511
|
+
# #
|
|
512
|
+
# # for subdir in dir.dir_members().values():
|
|
513
|
+
# # cls.createTree( subdir, node, label_max_length, num_cols )
|
|
514
|
+
# #
|
|
515
|
+
# # def typeTreeItemClicked( self, item: QTreeWidgetItem ):
|
|
516
|
+
# # self.onTagSelected( item.dir() )
|
|
517
|
+
# #
|
|
518
|
+
# # def onTagSelected( self, dir: Directory ):
|
|
519
|
+
# # if self.m_selectHook:
|
|
520
|
+
# # self.m_selectHook( dir )
|
|
521
|
+
#
|
|
522
|
+
# # class UxPixmap:
|
|
523
|
+
# # COLOR_AUTO = Qt.ColorScheme.AutoColor
|
|
524
|
+
# # COLOR_DITHER = Qt.ColorScheme.ColorOnly
|
|
525
|
+
# # COLOR_MONO = Qt.ColorScheme.MonoOnly
|
|
526
|
+
# # RATIO_IGNORE = Qt.ColorScheme.IgnoreAspectRatio
|
|
527
|
+
# # RATIO_KEEP = Qt.ColorScheme.KeepAspectRatio
|
|
528
|
+
# # RATIO_KEEP_EXP = Qt.ColorScheme.KeepAspectRatioByExpanding
|
|
529
|
+
# #
|
|
530
|
+
# # s_sourceTypeMap = {
|
|
531
|
+
# # str: QPixmap.load,
|
|
532
|
+
# # bytes: QPixmap.loadFromData,
|
|
533
|
+
# # bytearray: QPixmap.loadFromData,
|
|
534
|
+
# # }
|
|
535
|
+
# # def __init__( self, source = None, image_format = '', color_flags = COLOR_AUTO ):
|
|
536
|
+
# # self.m_pixmap = QPixmap()
|
|
537
|
+
# # rc = self.load( source, image_format = image_format, color_flags = color_flags )
|
|
538
|
+
# # if not rc:
|
|
539
|
+
# # raise RuntimeError( rc.err() )
|
|
540
|
+
# #
|
|
541
|
+
# # def load( self, source, image_format = '', color_flags = COLOR_AUTO ) -> RC:
|
|
542
|
+
# # if not source:
|
|
543
|
+
# # return RC( True )
|
|
544
|
+
# #
|
|
545
|
+
# # method = self.s_sourceTypeMap.get( type( source ) )
|
|
546
|
+
# # if not method:
|
|
547
|
+
# # return RC( False, f'UxPixmap - unknown type of source = {type( source )}' )
|
|
548
|
+
# #
|
|
549
|
+
# # rc = method( self.m_pixmap, source, format = image_format, flags = color_flags )
|
|
550
|
+
# # if not rc:
|
|
551
|
+
# # return RC( False, f'UxPixmap - failed to initialize from source = {source}' )
|
|
552
|
+
# #
|
|
553
|
+
# # return RC( True )
|
|
554
|
+
# #
|
|
555
|
+
# # def _toData( self, array: bytearray, format = '', quality = -1 ) -> bool:
|
|
556
|
+
# # buffer = QBuffer( array )
|
|
557
|
+
# # buffer.open( QIODevice.WriteOnly )
|
|
558
|
+
# # return self.m_pixmap.save( buffer, format = format, quality = quality )
|
|
559
|
+
# #
|
|
560
|
+
# # s_destinationTypeMap = {
|
|
561
|
+
# # str: QPixmap.save,
|
|
562
|
+
# # bytearray: _toData,
|
|
563
|
+
# # }
|
|
564
|
+
# # def save( self, destination, color_format = '', quality = -1 ) -> RC:
|
|
565
|
+
# # method = self.s_destinationTypeMap.get( type( destination ) )
|
|
566
|
+
# # if not method:
|
|
567
|
+
# # return RC( False, f'UxPixmap - unknown destination type = {type( destination )}' )
|
|
568
|
+
# #
|
|
569
|
+
# # rc = method( self, destination, format = color_format, quality = quality )
|
|
570
|
+
# # if not rc:
|
|
571
|
+
# # return RC( False, f'UxPixmap - failed to save to destination = {destination}' )
|
|
572
|
+
# #
|
|
573
|
+
# # return RC( True )
|
|
574
|
+
# #
|
|
575
|
+
# # def render( self, label: QLabel, w = 0, h = 0, scaled = RATIO_IGNORE, smooth = True ):
|
|
576
|
+
# # transform_mode = Qt.SmoothTransformation if smooth else Qt.FastTransformation
|
|
577
|
+
# # pixmap = self.m_pixmap
|
|
578
|
+
# # if w > 0 and h > 0:
|
|
579
|
+
# # pixmap = pixmap.scaled( w, h, aspectRatioMode = scaled, transformMode = transform_mode )
|
|
580
|
+
# # label.setPixmap( pixmap )
|
|
581
|
+
#
|
|
582
|
+
# @singleton
|
|
583
|
+
# class UxClipBoard:
|
|
584
|
+
# def __init__(self):
|
|
585
|
+
# self.dir = {}
|
|
586
|
+
# self.entity = None
|
|
587
|
+
# self.trait_name = ''
|
|
588
|
+
#
|
|
589
|
+
# # def copy(self, tag: str, value):
|
|
590
|
+
# # self.dir[tag] = value
|
|
591
|
+
# #
|
|
592
|
+
# # def paste(self, tag: str):
|
|
593
|
+
# # return self.dir.get(tag)
|
|
594
|
+
# #
|
|
595
|
+
# # def clear(self):
|
|
596
|
+
# # self.dir = {}
|
|
597
|
+
# #
|
|
598
|
+
# # def default_tag( self ) -> str:
|
|
599
|
+
# # assert self.entity and self.trait_name, 'entity and trait name are not defined'
|
|
600
|
+
# #
|
|
601
|
+
# # cls = self.entity.__class__
|
|
602
|
+
# # trait = cls.trait(self.trait_name)
|
|
603
|
+
# # assert trait, f"{cls}: unknown trait '{self.trait_name}'"
|
|
604
|
+
# # #tag_label = trait.label if trait.label else self.trait_name
|
|
605
|
+
# # tag_label = self.trait_name
|
|
606
|
+
# # return f"{self.entity}: '{tag_label}'"
|
|
607
|
+
# #
|
|
608
|
+
# # def layout(self) -> QWidget:
|
|
609
|
+
# # w = QWidget()
|
|
610
|
+
# # lay = QVBoxLayout()
|
|
611
|
+
# # w.setLayout(lay)
|
|
612
|
+
# #
|
|
613
|
+
# # add_row = QHBoxLayout()
|
|
614
|
+
# # add_b = uxPushButton('Add', callback = self.onCopy)
|
|
615
|
+
# # self.m_addNameWidget = add_name = QLineEdit()
|
|
616
|
+
# # add_name.setText(self.default_tag())
|
|
617
|
+
# # add_row.addWidget(add_b)
|
|
618
|
+
# # add_row.addWidget(add_name)
|
|
619
|
+
# # lay.addLayout(add_row)
|
|
620
|
+
# #
|
|
621
|
+
# # lay.addWidget(uxSeparator())
|
|
622
|
+
# #
|
|
623
|
+
# # self.m_sl = sl = UxSearchableList(choices = list( self.dir.keys() ), select_hook = self.onPaste, title = 'Use Data')
|
|
624
|
+
# # lay.addWidget(sl)
|
|
625
|
+
# #
|
|
626
|
+
# # return w
|
|
627
|
+
# #
|
|
628
|
+
# # def popup(self, parent_widget: QWidget, entity, trait_name: str):
|
|
629
|
+
# # self.m_parent = parent_widget
|
|
630
|
+
# # self.entity = entity
|
|
631
|
+
# # self.trait_name = trait_name
|
|
632
|
+
# # self.m_d = d = UxDialog(self.layout(), parent = parent_widget, cancel = '', title = 'Copy or Paste Data')
|
|
633
|
+
# # d.exec()
|
|
634
|
+
# #
|
|
635
|
+
# # def onCopy(self):
|
|
636
|
+
# # name = self.m_addNameWidget.text()
|
|
637
|
+
# # if name:
|
|
638
|
+
# # value = self.entity.get_value( self.trait_name )
|
|
639
|
+
# # if value is not None:
|
|
640
|
+
# # self.copy( name, value )
|
|
641
|
+
# #
|
|
642
|
+
# # self.m_d.close()
|
|
643
|
+
# #
|
|
644
|
+
# # def onPaste( self, name: str ):
|
|
645
|
+
# # value = self.paste( name )
|
|
646
|
+
# # if value is not None:
|
|
647
|
+
# # rc = self.m_entity.setValue( self.m_traitName, value )
|
|
648
|
+
# # if not rc:
|
|
649
|
+
# # uxWarning(
|
|
650
|
+
# # f"Data '{name}' is not suitable for '{self.m_entity.trait( self.m_traitName ).m_label}'",
|
|
651
|
+
# # parent = self.m_parent,
|
|
652
|
+
# # title = 'Invalid Data'
|
|
653
|
+
# # )
|
|
654
|
+
# #
|
|
655
|
+
# # self.m_d.close()
|
|
656
|
+
#
|
|
657
|
+
# @cache
|
|
658
|
+
# def uxInit(style = '') -> QApplication:
|
|
659
|
+
# if not style:
|
|
660
|
+
# style = platform.system()
|
|
661
|
+
#
|
|
662
|
+
# app = QApplication([])
|
|
663
|
+
# app.setStyle(style)
|
|
664
|
+
# return app
|
|
665
|
+
#
|
ui_10x/rio/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from ui_10x.rio.component_builder import UserSessionContext
|
|
4
|
+
|
|
5
|
+
import rio
|
|
6
|
+
|
|
7
|
+
theme = rio.Theme.from_colors(
|
|
8
|
+
primary_color=rio.Color.from_hex('01dffdff'),
|
|
9
|
+
secondary_color=rio.Color.from_hex('0083ffff'),
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def on_session_start(session):
|
|
14
|
+
session.attach(UserSessionContext(host='localhost', dbname='test')) # TODO: backbone
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
app = rio.App(
|
|
18
|
+
name='ui_10x.rio.apps.examples',
|
|
19
|
+
description='Rio pages based on components created using ui_10x.platform_interface',
|
|
20
|
+
theme=theme,
|
|
21
|
+
on_session_start=on_session_start,
|
|
22
|
+
)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from ui_10x.collection_editor import Collection, CollectionEditor
|
|
4
|
+
from ui_10x.rio.component_builder import UserSessionContext
|
|
5
|
+
from ui_10x.utils import UxDialog
|
|
6
|
+
|
|
7
|
+
import rio
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class CollectionEditorComponent(rio.Component):
|
|
11
|
+
collection_class: type = None
|
|
12
|
+
|
|
13
|
+
def build(self) -> rio.Component:
|
|
14
|
+
with self.session[UserSessionContext]:
|
|
15
|
+
return UxDialog(CollectionEditor(coll=Collection(cls=self.collection_class)).main_widget()).build(self.session)
|