gui-utilities 1.3.40__tar.gz → 1.4.3__tar.gz
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.
- {gui_utilities-1.3.40 → gui_utilities-1.4.3}/PKG-INFO +1 -1
- {gui_utilities-1.3.40 → gui_utilities-1.4.3}/gui_utilities/gui_utilities.py +232 -95
- {gui_utilities-1.3.40 → gui_utilities-1.4.3}/gui_utilities.egg-info/PKG-INFO +1 -1
- {gui_utilities-1.3.40 → gui_utilities-1.4.3}/pyproject.toml +1 -1
- {gui_utilities-1.3.40 → gui_utilities-1.4.3}/LICENSE +0 -0
- {gui_utilities-1.3.40 → gui_utilities-1.4.3}/README.md +0 -0
- {gui_utilities-1.3.40 → gui_utilities-1.4.3}/gui_utilities/icons/focused_hide_text_icon.png +0 -0
- {gui_utilities-1.3.40 → gui_utilities-1.4.3}/gui_utilities/icons/focused_show_text_icon.png +0 -0
- {gui_utilities-1.3.40 → gui_utilities-1.4.3}/gui_utilities/icons/hide_text_icon.png +0 -0
- {gui_utilities-1.3.40 → gui_utilities-1.4.3}/gui_utilities/icons/show_text_icon.png +0 -0
- {gui_utilities-1.3.40 → gui_utilities-1.4.3}/gui_utilities/tlds/tlds_list.txt +0 -0
- {gui_utilities-1.3.40 → gui_utilities-1.4.3}/gui_utilities.egg-info/SOURCES.txt +0 -0
- {gui_utilities-1.3.40 → gui_utilities-1.4.3}/gui_utilities.egg-info/dependency_links.txt +0 -0
- {gui_utilities-1.3.40 → gui_utilities-1.4.3}/gui_utilities.egg-info/requires.txt +0 -0
- {gui_utilities-1.3.40 → gui_utilities-1.4.3}/gui_utilities.egg-info/top_level.txt +0 -0
- {gui_utilities-1.3.40 → gui_utilities-1.4.3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from PyQt6.QtCore import Qt, QObject, QEvent, QSize
|
|
2
|
-
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QLineEdit, QComboBox, QDialog, QToolButton, QWidgetAction, QCheckBox, QTableWidget, QHeaderView
|
|
3
|
-
from PyQt6.QtGui import QIcon
|
|
2
|
+
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QLineEdit, QComboBox, QDialog, QToolButton, QWidgetAction, QCheckBox, QTableWidget, QHeaderView, QApplication, QStyle, QStyledItemDelegate, QScrollArea
|
|
3
|
+
from PyQt6.QtGui import QIcon, QTextDocument
|
|
4
4
|
import re
|
|
5
5
|
import requests
|
|
6
6
|
import importlib.resources
|
|
@@ -9,8 +9,8 @@ main_dir = importlib.resources.files("gui_utilities")
|
|
|
9
9
|
icons_dir = main_dir / "icons"
|
|
10
10
|
tlds_path = main_dir / "tlds"
|
|
11
11
|
|
|
12
|
-
def create_window(title, background_color = "#1e1e1e"):
|
|
13
|
-
window = QWidget()
|
|
12
|
+
def create_window(title, background_color = "#1e1e1e", parent = None):
|
|
13
|
+
window = QWidget(parent)
|
|
14
14
|
window.setObjectName("window")
|
|
15
15
|
window.setWindowTitle(title)
|
|
16
16
|
window.setStyleSheet(f"#window {{background-color: {background_color};}}")
|
|
@@ -33,7 +33,9 @@ def create_menu(
|
|
|
33
33
|
title_padding_bottom = None,
|
|
34
34
|
title_border_width = 0,
|
|
35
35
|
title_border_color = "#ffffff",
|
|
36
|
-
title_border_radius = 0
|
|
36
|
+
title_border_radius = 0,
|
|
37
|
+
math_expression = False,
|
|
38
|
+
title_alignment = Qt.AlignmentFlag.AlignCenter
|
|
37
39
|
):
|
|
38
40
|
main_layout = QVBoxLayout()
|
|
39
41
|
main_layout.setContentsMargins(25, 25, 25, 25)
|
|
@@ -50,7 +52,9 @@ def create_menu(
|
|
|
50
52
|
padding_bottom = title_padding_bottom,
|
|
51
53
|
border_width = title_border_width,
|
|
52
54
|
border_color = title_border_color,
|
|
53
|
-
border_radius = title_border_radius
|
|
55
|
+
border_radius = title_border_radius,
|
|
56
|
+
math_expression = math_expression,
|
|
57
|
+
alignment = title_alignment
|
|
54
58
|
))
|
|
55
59
|
body_layout = QHBoxLayout()
|
|
56
60
|
main_layout.addLayout(body_layout)
|
|
@@ -79,8 +83,18 @@ def create_menu(
|
|
|
79
83
|
menu_layout.addWidget(button)
|
|
80
84
|
ui_instance.content_widget = QWidget()
|
|
81
85
|
ui_instance.content_widget.setLayout(QVBoxLayout())
|
|
82
|
-
body_layout.addWidget(ui_instance.content_widget)
|
|
83
86
|
ui_instance.content_widget.setStyleSheet("background-color: #333333;")
|
|
87
|
+
scroll_area = QScrollArea()
|
|
88
|
+
scroll_area.setWidgetResizable(True)
|
|
89
|
+
scroll_area.setWidget(ui_instance.content_widget)
|
|
90
|
+
style_sheet = """
|
|
91
|
+
QScrollArea {
|
|
92
|
+
border: none;
|
|
93
|
+
background-color: #333333;
|
|
94
|
+
}
|
|
95
|
+
"""
|
|
96
|
+
scroll_area.setStyleSheet(style_sheet)
|
|
97
|
+
body_layout.addWidget(scroll_area)
|
|
84
98
|
body_layout.setStretch(0, 1)
|
|
85
99
|
body_layout.setStretch(1, 4)
|
|
86
100
|
return main_layout
|
|
@@ -102,7 +116,9 @@ def create_header(
|
|
|
102
116
|
title_padding_bottom = None,
|
|
103
117
|
title_border_width = 0,
|
|
104
118
|
title_border_color = "#ffffff",
|
|
105
|
-
title_border_radius = 0
|
|
119
|
+
title_border_radius = 0,
|
|
120
|
+
math_expression = False,
|
|
121
|
+
title_alignment = Qt.AlignmentFlag.AlignCenter
|
|
106
122
|
):
|
|
107
123
|
main_layout = QVBoxLayout()
|
|
108
124
|
main_layout.setContentsMargins(margin_left, margin_top, margin_right, margin_bottom)
|
|
@@ -119,7 +135,9 @@ def create_header(
|
|
|
119
135
|
padding_bottom = title_padding_bottom,
|
|
120
136
|
border_width = title_border_width,
|
|
121
137
|
border_color = title_border_color,
|
|
122
|
-
border_radius = title_border_radius
|
|
138
|
+
border_radius = title_border_radius,
|
|
139
|
+
math_expression = math_expression,
|
|
140
|
+
alignment = title_alignment
|
|
123
141
|
)
|
|
124
142
|
main_layout.addLayout(title_layout)
|
|
125
143
|
main_layout.addStretch()
|
|
@@ -138,11 +156,12 @@ def create_title(
|
|
|
138
156
|
padding_bottom = None,
|
|
139
157
|
border_width = 0,
|
|
140
158
|
border_color = "#ffffff",
|
|
141
|
-
border_radius = 0
|
|
159
|
+
border_radius = 0,
|
|
160
|
+
math_expression = False,
|
|
161
|
+
alignment = Qt.AlignmentFlag.AlignCenter
|
|
142
162
|
):
|
|
143
163
|
title_layout = QHBoxLayout()
|
|
144
164
|
title_layout.setContentsMargins(0, 0, 0, 25)
|
|
145
|
-
title_layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
146
165
|
title_label = create_label(
|
|
147
166
|
text = text,
|
|
148
167
|
font_family = font_family,
|
|
@@ -157,7 +176,9 @@ def create_title(
|
|
|
157
176
|
padding_bottom = padding_bottom,
|
|
158
177
|
border_width = border_width,
|
|
159
178
|
border_color = border_color,
|
|
160
|
-
border_radius = border_radius
|
|
179
|
+
border_radius = border_radius,
|
|
180
|
+
math_expression = math_expression,
|
|
181
|
+
alignment = alignment
|
|
161
182
|
)
|
|
162
183
|
title_layout.addWidget(title_label)
|
|
163
184
|
return title_layout
|
|
@@ -184,9 +205,19 @@ def create_label(
|
|
|
184
205
|
disabled_background_color = "transparent",
|
|
185
206
|
disabled_border_width = 0,
|
|
186
207
|
disabled_border_color = "#4a4a4a",
|
|
208
|
+
math_expression = False,
|
|
209
|
+
transparent_for_mouse = False,
|
|
210
|
+
alignment = None,
|
|
211
|
+
word_wrap = False,
|
|
187
212
|
parent = None
|
|
188
213
|
):
|
|
189
|
-
|
|
214
|
+
if math_expression:
|
|
215
|
+
label = QLabel(format_html(text), parent)
|
|
216
|
+
label.setTextFormat(Qt.TextFormat.RichText)
|
|
217
|
+
else: label = QLabel(text, parent)
|
|
218
|
+
if transparent_for_mouse: label.setAttribute(Qt.WidgetAttribute.WA_TransparentForMouseEvents, True)
|
|
219
|
+
if alignment: label.setAlignment(alignment)
|
|
220
|
+
if word_wrap: label.setWordWrap(True)
|
|
190
221
|
padding_left_value = padding_left if padding_left is not None else padding
|
|
191
222
|
padding_top_value = padding_top if padding_top is not None else padding
|
|
192
223
|
padding_right_value = padding_right if padding_right is not None else padding
|
|
@@ -243,10 +274,12 @@ def create_button(
|
|
|
243
274
|
disabled_background_color = "#2d2d2d",
|
|
244
275
|
disabled_border_width = 2,
|
|
245
276
|
disabled_border_color = "#4a4a4a",
|
|
246
|
-
maximum_width = 360
|
|
277
|
+
maximum_width = 360,
|
|
278
|
+
math_expression = False,
|
|
279
|
+
parent = None
|
|
247
280
|
):
|
|
248
|
-
button = QPushButton()
|
|
249
|
-
button.setMaximumWidth(maximum_width)
|
|
281
|
+
button = QPushButton(parent)
|
|
282
|
+
if maximum_width is not None: button.setMaximumWidth(maximum_width)
|
|
250
283
|
main_layout = QVBoxLayout()
|
|
251
284
|
button.setLayout(main_layout)
|
|
252
285
|
main_layout.setContentsMargins(0, 0, 0, 0)
|
|
@@ -260,9 +293,11 @@ def create_button(
|
|
|
260
293
|
padding_top = padding_top,
|
|
261
294
|
padding_right = padding_right,
|
|
262
295
|
padding_bottom = padding_bottom,
|
|
263
|
-
disabled_border_width = disabled_border_width
|
|
296
|
+
disabled_border_width = disabled_border_width,
|
|
297
|
+
transparent_for_mouse = True,
|
|
298
|
+
alignment = Qt.AlignmentFlag.AlignCenter,
|
|
299
|
+
math_expression = math_expression
|
|
264
300
|
)
|
|
265
|
-
label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
266
301
|
label.setWordWrap(True)
|
|
267
302
|
main_layout.addWidget(label)
|
|
268
303
|
button.setFixedHeight(main_layout.sizeHint().height() + 2 * border_width)
|
|
@@ -332,9 +367,10 @@ def create_text_box(
|
|
|
332
367
|
focused_show_text_icon_url = str(icons_dir / "focused_show_text_icon.png"),
|
|
333
368
|
focused_hide_text_icon_url = str(icons_dir / "focused_hide_text_icon.png"),
|
|
334
369
|
hide_text = False,
|
|
335
|
-
math_expression = False
|
|
370
|
+
math_expression = False,
|
|
371
|
+
parent = None
|
|
336
372
|
):
|
|
337
|
-
text_box = QLineEdit()
|
|
373
|
+
text_box = QLineEdit(parent)
|
|
338
374
|
padding_left_value = padding_left if padding_left is not None else padding
|
|
339
375
|
padding_top_value = padding_top if padding_top is not None else padding
|
|
340
376
|
padding_right_value = padding_right if padding_right is not None else padding
|
|
@@ -368,53 +404,6 @@ def create_text_box(
|
|
|
368
404
|
}}
|
|
369
405
|
"""
|
|
370
406
|
text_box.setStyleSheet(style_sheet)
|
|
371
|
-
|
|
372
|
-
def latex_to_html(expression):
|
|
373
|
-
html_expression = expression
|
|
374
|
-
html_expression = re.sub(r"\\frac\{(.*?)\}\{(.*?)\}", r"<span style='font-size:90%;'>\1⁄\2</span>", html_expression)
|
|
375
|
-
html_expression = re.sub(r"([a-zA-Z])_(\d+)", r"\1<sub>\2</sub>", html_expression)
|
|
376
|
-
html_expression = re.sub(r"([a-zA-Z0-9])\^(\d+)", r"\1<sup>\2</sup>", html_expression)
|
|
377
|
-
html_expression = html_expression.replace(" ", " ")
|
|
378
|
-
return html_expression
|
|
379
|
-
|
|
380
|
-
if not math_expression: text_box.setPlaceholderText(placeholder_text)
|
|
381
|
-
else:
|
|
382
|
-
html_placeholder = latex_to_html(placeholder_text)
|
|
383
|
-
placeholder_label = create_label(
|
|
384
|
-
text = html_placeholder,
|
|
385
|
-
font_color = placeholder_font_color,
|
|
386
|
-
font_family = font_family,
|
|
387
|
-
font_size = font_size,
|
|
388
|
-
background_color = "transparent",
|
|
389
|
-
disabled_background_color = "transparent",
|
|
390
|
-
parent = text_box
|
|
391
|
-
)
|
|
392
|
-
placeholder_label.setTextFormat(Qt.TextFormat.RichText)
|
|
393
|
-
placeholder_label.setAttribute(Qt.WidgetAttribute.WA_TransparentForMouseEvents, True)
|
|
394
|
-
placeholder_label.move(0, -2)
|
|
395
|
-
placeholder_label.show()
|
|
396
|
-
|
|
397
|
-
class _PlaceholderFocusWatcher(QObject):
|
|
398
|
-
|
|
399
|
-
def __init__(self, watched, placeholder_label):
|
|
400
|
-
super().__init__(watched)
|
|
401
|
-
self._watched = watched
|
|
402
|
-
self._placeholder = placeholder_label
|
|
403
|
-
|
|
404
|
-
def eventFilter(self, watched, event):
|
|
405
|
-
if watched is self._watched and event.type() in (QEvent.Type.FocusIn, QEvent.Type.FocusOut):
|
|
406
|
-
self._placeholder.setVisible((self._watched.text() == "") and (not self._watched.hasFocus()))
|
|
407
|
-
return super().eventFilter(watched, event)
|
|
408
|
-
|
|
409
|
-
def _update_placeholder_visibility():
|
|
410
|
-
if placeholder_label is not None:
|
|
411
|
-
placeholder_label.setVisible(text_box.text() == "" and not text_box.hasFocus())
|
|
412
|
-
|
|
413
|
-
text_box.textChanged.connect(_update_placeholder_visibility)
|
|
414
|
-
focus_watcher_placeholder = _PlaceholderFocusWatcher(text_box, placeholder_label)
|
|
415
|
-
text_box.installEventFilter(focus_watcher_placeholder)
|
|
416
|
-
setattr(text_box, "_placeholder_focus_watcher", focus_watcher_placeholder)
|
|
417
|
-
_update_placeholder_visibility()
|
|
418
407
|
if hide_text:
|
|
419
408
|
show_text_icon = QIcon(show_text_icon_url)
|
|
420
409
|
hide_text_icon = QIcon(hide_text_icon_url)
|
|
@@ -436,7 +425,7 @@ def create_text_box(
|
|
|
436
425
|
margin-right: 10px;
|
|
437
426
|
}
|
|
438
427
|
""")
|
|
439
|
-
|
|
428
|
+
|
|
440
429
|
def update_icon():
|
|
441
430
|
is_password = text_box.echoMode() == QLineEdit.EchoMode.Password
|
|
442
431
|
if text_box.hasFocus(): icon = focused_hide_text_icon if is_password else focused_show_text_icon
|
|
@@ -451,7 +440,6 @@ def create_text_box(
|
|
|
451
440
|
toggle_text_visibility_button.clicked.connect(toggle_visibility)
|
|
452
441
|
|
|
453
442
|
class _IconFocusWatcher(QObject):
|
|
454
|
-
|
|
455
443
|
def __init__(self, watched, on_focus_change):
|
|
456
444
|
super().__init__(watched)
|
|
457
445
|
self._watched = watched
|
|
@@ -465,7 +453,45 @@ def create_text_box(
|
|
|
465
453
|
icon_focus_watcher = _IconFocusWatcher(text_box, update_icon)
|
|
466
454
|
text_box.installEventFilter(icon_focus_watcher)
|
|
467
455
|
setattr(text_box, "_icon_focus_watcher", icon_focus_watcher)
|
|
468
|
-
|
|
456
|
+
|
|
457
|
+
placeholder_label = create_label(
|
|
458
|
+
text = placeholder_text,
|
|
459
|
+
font_family = font_family,
|
|
460
|
+
font_size = font_size,
|
|
461
|
+
font_color = placeholder_font_color,
|
|
462
|
+
font_weight = font_weight,
|
|
463
|
+
padding = padding,
|
|
464
|
+
padding_left = padding_left,
|
|
465
|
+
padding_top = padding_top,
|
|
466
|
+
padding_right = padding_right,
|
|
467
|
+
padding_bottom = padding_bottom,
|
|
468
|
+
math_expression = math_expression,
|
|
469
|
+
transparent_for_mouse = True,
|
|
470
|
+
parent = text_box
|
|
471
|
+
)
|
|
472
|
+
placeholder_label.move(0, 2)
|
|
473
|
+
|
|
474
|
+
def update_placeholder_visibility():
|
|
475
|
+
has_text = bool(text_box.text().strip())
|
|
476
|
+
has_focus = text_box.hasFocus()
|
|
477
|
+
placeholder_label.setVisible(not has_text and not has_focus)
|
|
478
|
+
if hide_text: update_icon()
|
|
479
|
+
|
|
480
|
+
class _PlaceholderFocusWatcher(QObject):
|
|
481
|
+
def __init__(self, watched, on_focus_change):
|
|
482
|
+
super().__init__(watched)
|
|
483
|
+
self._watched = watched
|
|
484
|
+
self._on_focus_change = on_focus_change
|
|
485
|
+
|
|
486
|
+
def eventFilter(self, watched, event):
|
|
487
|
+
if watched is self._watched and event.type() in (QEvent.Type.FocusIn, QEvent.Type.FocusOut):
|
|
488
|
+
if callable(self._on_focus_change): self._on_focus_change()
|
|
489
|
+
return super().eventFilter(watched, event)
|
|
490
|
+
|
|
491
|
+
placeholder_focus_watcher = _PlaceholderFocusWatcher(text_box, update_placeholder_visibility)
|
|
492
|
+
text_box.installEventFilter(placeholder_focus_watcher)
|
|
493
|
+
setattr(text_box, "_placeholder_focus_watcher", placeholder_focus_watcher)
|
|
494
|
+
update_placeholder_visibility()
|
|
469
495
|
return text_box
|
|
470
496
|
|
|
471
497
|
def create_combo_box(
|
|
@@ -495,21 +521,108 @@ def create_combo_box(
|
|
|
495
521
|
dropdown_background_color = "#1e1e1e",
|
|
496
522
|
dropdown_selection_background_color = "#0078d7",
|
|
497
523
|
dropdown_border_width = 1,
|
|
498
|
-
dropdown_border_color = "#5c5c5c"
|
|
524
|
+
dropdown_border_color = "#5c5c5c",
|
|
525
|
+
math_expression = False,
|
|
526
|
+
parent = None
|
|
499
527
|
):
|
|
500
|
-
combo_box = QComboBox()
|
|
501
|
-
combo_box.
|
|
502
|
-
combo_box.addItems(items)
|
|
503
|
-
combo_box.setCurrentIndex(-1)
|
|
504
|
-
|
|
528
|
+
combo_box = QComboBox(parent)
|
|
529
|
+
combo_box.setAccessibleName("combo_box")
|
|
505
530
|
padding_left_value = padding_left if padding_left is not None else padding
|
|
506
531
|
padding_top_value = padding_top if padding_top is not None else padding
|
|
507
532
|
padding_right_value = padding_right if padding_right is not None else padding
|
|
508
533
|
padding_bottom_value = padding_bottom if padding_bottom is not None else padding
|
|
534
|
+
if math_expression:
|
|
535
|
+
placeholder_label = create_label(
|
|
536
|
+
text = placeholder_text,
|
|
537
|
+
font_family = font_family,
|
|
538
|
+
font_size = font_size,
|
|
539
|
+
font_color = placeholder_font_color,
|
|
540
|
+
padding = padding,
|
|
541
|
+
padding_left = padding_left,
|
|
542
|
+
padding_top = padding_top,
|
|
543
|
+
padding_right = padding_right,
|
|
544
|
+
padding_bottom = padding_bottom,
|
|
545
|
+
math_expression = True,
|
|
546
|
+
transparent_for_mouse = True,
|
|
547
|
+
parent = combo_box
|
|
548
|
+
)
|
|
549
|
+
placeholder_label.move(0, 2)
|
|
550
|
+
|
|
551
|
+
def update_placeholder_visibility():
|
|
552
|
+
has_selection = combo_box.currentIndex() != -1
|
|
553
|
+
placeholder_label.setVisible(not has_selection)
|
|
554
|
+
|
|
555
|
+
combo_box.currentIndexChanged.connect(update_placeholder_visibility)
|
|
556
|
+
update_placeholder_visibility()
|
|
557
|
+
|
|
558
|
+
class RichTextDelegate(QStyledItemDelegate):
|
|
559
|
+
def __init__(
|
|
560
|
+
self,
|
|
561
|
+
parent = None,
|
|
562
|
+
font_color = "#ffffff",
|
|
563
|
+
selection_font_color = "#ffffff"
|
|
564
|
+
):
|
|
565
|
+
super().__init__(parent)
|
|
566
|
+
self.font_color = font_color
|
|
567
|
+
self.selection_font_color = selection_font_color
|
|
509
568
|
|
|
569
|
+
def paint(self, painter, option, index):
|
|
570
|
+
if option.state & QStyle.StateFlag.State_Selected: text_color = self.selection_font_color
|
|
571
|
+
else: text_color = self.font_color
|
|
572
|
+
document = QTextDocument()
|
|
573
|
+
html = f"<span style = \"color:{text_color};\">{index.data(Qt.ItemDataRole.DisplayRole)}</span>"
|
|
574
|
+
document.setHtml(html)
|
|
575
|
+
option.text = ""
|
|
576
|
+
QApplication.style().drawControl(QStyle.ControlElement.CE_ItemViewItem, option, painter)
|
|
577
|
+
painter.save()
|
|
578
|
+
painter.translate(option.rect.left(), option.rect.top() + (option.rect.height() - document.size().height()) / 2)
|
|
579
|
+
document.drawContents(painter)
|
|
580
|
+
painter.restore()
|
|
581
|
+
|
|
582
|
+
delegate = RichTextDelegate(
|
|
583
|
+
parent = combo_box,
|
|
584
|
+
font_color = dropdown_font_color,
|
|
585
|
+
selection_font_color = font_color
|
|
586
|
+
)
|
|
587
|
+
combo_box.setItemDelegate(delegate)
|
|
588
|
+
combo_box.clear()
|
|
589
|
+
for item in items: combo_box.addItem(format_html(item))
|
|
590
|
+
combo_box.view().setTextElideMode(Qt.TextElideMode.ElideNone)
|
|
591
|
+
else:
|
|
592
|
+
combo_box.setPlaceholderText(placeholder_text)
|
|
593
|
+
combo_box.addItems(items)
|
|
594
|
+
combo_box.setCurrentIndex(-1)
|
|
595
|
+
if math_expression:
|
|
596
|
+
selected_item_label = create_label(
|
|
597
|
+
text = "",
|
|
598
|
+
font_family = font_family,
|
|
599
|
+
font_size = font_size,
|
|
600
|
+
font_color = font_color,
|
|
601
|
+
padding = padding,
|
|
602
|
+
padding_left = padding_left,
|
|
603
|
+
padding_top = padding_top,
|
|
604
|
+
padding_right = padding_right,
|
|
605
|
+
padding_bottom = padding_bottom,
|
|
606
|
+
math_expression = True,
|
|
607
|
+
transparent_for_mouse = True,
|
|
608
|
+
alignment = Qt.AlignmentFlag.AlignCenter,
|
|
609
|
+
parent = combo_box
|
|
610
|
+
)
|
|
611
|
+
selected_item_label.setVisible(False)
|
|
612
|
+
|
|
613
|
+
def update_selected_item_display(index):
|
|
614
|
+
if index != -1:
|
|
615
|
+
html_text = combo_box.itemText(index)
|
|
616
|
+
selected_item_label.setText(html_text)
|
|
617
|
+
selected_item_label.setVisible(True)
|
|
618
|
+
else:
|
|
619
|
+
selected_item_label.setVisible(False)
|
|
620
|
+
|
|
621
|
+
combo_box.currentIndexChanged.connect(update_selected_item_display)
|
|
622
|
+
|
|
510
623
|
def get_stylesheet(font_color):
|
|
511
624
|
return f"""
|
|
512
|
-
QComboBox {{
|
|
625
|
+
QComboBox[accessibleName="combo_box"] {{
|
|
513
626
|
font-family: {font_family};
|
|
514
627
|
font-size: {font_size}px;
|
|
515
628
|
color: {font_color};
|
|
@@ -521,12 +634,12 @@ def create_combo_box(
|
|
|
521
634
|
border: {border_width}px solid {border_color};
|
|
522
635
|
border-radius: {border_radius}px;
|
|
523
636
|
}}
|
|
524
|
-
QComboBox:hover {{
|
|
637
|
+
QComboBox[accessibleName="combo_box"]:hover {{
|
|
525
638
|
background-color: {hover_background_color};
|
|
526
639
|
border: {hover_border_width}px solid {hover_border_color};
|
|
527
640
|
}}
|
|
528
|
-
QComboBox:on {{
|
|
529
|
-
color: {on_font_color};
|
|
641
|
+
QComboBox[accessibleName="combo_box"]:on {{
|
|
642
|
+
color: {"transparent" if math_expression else on_font_color};
|
|
530
643
|
background-color: {on_background_color};
|
|
531
644
|
border: {on_border_width}px solid {on_border_color};
|
|
532
645
|
}}
|
|
@@ -542,8 +655,12 @@ def create_combo_box(
|
|
|
542
655
|
"""
|
|
543
656
|
|
|
544
657
|
def change_color(index):
|
|
545
|
-
if index == -1:
|
|
546
|
-
|
|
658
|
+
if index == -1:
|
|
659
|
+
text_color = "transparent" if math_expression else placeholder_font_color
|
|
660
|
+
combo_box.setStyleSheet(get_stylesheet(text_color))
|
|
661
|
+
else:
|
|
662
|
+
text_color = "transparent" if math_expression else font_color
|
|
663
|
+
combo_box.setStyleSheet(get_stylesheet(text_color))
|
|
547
664
|
|
|
548
665
|
combo_box.currentIndexChanged.connect(change_color)
|
|
549
666
|
change_color(-1)
|
|
@@ -576,9 +693,10 @@ def create_checkbox(
|
|
|
576
693
|
disabled_font_color = "#888888",
|
|
577
694
|
disabled_background_color = "#2d2d2d",
|
|
578
695
|
disabled_border_width = 1,
|
|
579
|
-
disabled_border_color = "#4a4a4a"
|
|
696
|
+
disabled_border_color = "#4a4a4a",
|
|
697
|
+
parent = None
|
|
580
698
|
):
|
|
581
|
-
check_box = QCheckBox(text)
|
|
699
|
+
check_box = QCheckBox(text, parent)
|
|
582
700
|
padding_left_value = padding_left if padding_left is not None else padding
|
|
583
701
|
padding_top_value = padding_top if padding_top is not None else padding
|
|
584
702
|
padding_right_value = padding_right if padding_right is not None else padding
|
|
@@ -669,9 +787,10 @@ def create_information_message_box(
|
|
|
669
787
|
button_disabled_font_color = "#888888",
|
|
670
788
|
button_disabled_background_color = "#2d2d2d",
|
|
671
789
|
button_disabled_border_width = 2,
|
|
672
|
-
button_disabled_border_color = "#4a4a4a"
|
|
790
|
+
button_disabled_border_color = "#4a4a4a",
|
|
791
|
+
parent = None
|
|
673
792
|
):
|
|
674
|
-
message_box = QDialog()
|
|
793
|
+
message_box = QDialog(parent)
|
|
675
794
|
message_box.setObjectName("message_box")
|
|
676
795
|
message_box.setWindowFlags(Qt.WindowType.FramelessWindowHint)
|
|
677
796
|
message_box.setFixedWidth(360)
|
|
@@ -700,10 +819,10 @@ def create_information_message_box(
|
|
|
700
819
|
padding_bottom = label_padding_bottom,
|
|
701
820
|
border_width = label_border_width,
|
|
702
821
|
border_color = label_border_color,
|
|
703
|
-
border_radius = label_border_radius
|
|
822
|
+
border_radius = label_border_radius,
|
|
823
|
+
alignment = Qt.AlignmentFlag.AlignCenter
|
|
704
824
|
)
|
|
705
825
|
main_layout.addWidget(text_label)
|
|
706
|
-
text_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
707
826
|
text_label.setWordWrap(True)
|
|
708
827
|
accept_button = create_button(
|
|
709
828
|
text = button_text,
|
|
@@ -778,9 +897,10 @@ def create_confirmation_message_box(
|
|
|
778
897
|
button_disabled_font_color = "#888888",
|
|
779
898
|
button_disabled_background_color = "#2d2d2d",
|
|
780
899
|
button_disabled_border_width = 2,
|
|
781
|
-
button_disabled_border_color = "#4a4a4a"
|
|
900
|
+
button_disabled_border_color = "#4a4a4a",
|
|
901
|
+
parent = None
|
|
782
902
|
):
|
|
783
|
-
confirm_message_box = QDialog()
|
|
903
|
+
confirm_message_box = QDialog(parent)
|
|
784
904
|
confirm_message_box.setObjectName("confirm_message_box")
|
|
785
905
|
confirm_message_box.setWindowFlags(Qt.WindowType.FramelessWindowHint)
|
|
786
906
|
confirm_message_box.setFixedWidth(360)
|
|
@@ -809,10 +929,10 @@ def create_confirmation_message_box(
|
|
|
809
929
|
padding_bottom = label_padding_bottom,
|
|
810
930
|
border_width = label_border_width,
|
|
811
931
|
border_color = label_border_color,
|
|
812
|
-
border_radius = label_border_radius
|
|
932
|
+
border_radius = label_border_radius,
|
|
933
|
+
alignment = Qt.AlignmentFlag.AlignCenter
|
|
813
934
|
)
|
|
814
935
|
main_layout.addWidget(text_label)
|
|
815
|
-
text_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
816
936
|
text_label.setWordWrap(True)
|
|
817
937
|
buttons_layout = QHBoxLayout()
|
|
818
938
|
main_layout.addLayout(buttons_layout)
|
|
@@ -907,9 +1027,10 @@ def create_list_table(
|
|
|
907
1027
|
hover_scrollbar_handle_border_color = "#777777",
|
|
908
1028
|
pressed_scrollbar_handle_background_color = "#4a4a4a",
|
|
909
1029
|
pressed_scrollbar_handle_border_width = 3,
|
|
910
|
-
pressed_scrollbar_handle_border_color = "#0078d7"
|
|
1030
|
+
pressed_scrollbar_handle_border_color = "#0078d7",
|
|
1031
|
+
parent = None
|
|
911
1032
|
):
|
|
912
|
-
list_table = QTableWidget()
|
|
1033
|
+
list_table = QTableWidget(parent)
|
|
913
1034
|
list_table.verticalHeader().setVisible(False)
|
|
914
1035
|
list_table.setColumnCount(len(column_headers))
|
|
915
1036
|
list_table.setHorizontalHeaderLabels(column_headers)
|
|
@@ -1119,6 +1240,12 @@ def validate_integer(integer, suffix = "El", field = "campo"):
|
|
|
1119
1240
|
if pattern.match(unformatted_integer): return None
|
|
1120
1241
|
return f"No ha ingresado {"un" if suffix == "El" else "una"} {field} {"válido" if suffix == "El" else "válida"}."
|
|
1121
1242
|
|
|
1243
|
+
def validate_float(decimal, suffix = "El", field = "campo"):
|
|
1244
|
+
if not decimal or not decimal.strip(): return f"{suffix} {field} no puede dejarse {"vacío" if suffix == "El" else "vacía"}."
|
|
1245
|
+
pattern = re.compile(r"^-?\d{1,3}(?:\.\d{3})*(?:,\d+)?$|^-?\d+(?:,\d+)?$")
|
|
1246
|
+
if not pattern.match(decimal): return None
|
|
1247
|
+
return f"No ha ingresado {"un" if suffix == "El" else "una"} {field} {"válido" if suffix == "El" else "válida"}."
|
|
1248
|
+
|
|
1122
1249
|
def validate_id(id_str):
|
|
1123
1250
|
if not id_str or not id_str.strip(): return "El D.N.I. no puede dejarse vacio."
|
|
1124
1251
|
pattern = re.compile(r"^(?:\d{8}|(?:\d{1,2}\.\d{3}\.\d{3}))$")
|
|
@@ -1196,4 +1323,14 @@ def format_date(date):
|
|
|
1196
1323
|
day = f"{date.day:02d}"
|
|
1197
1324
|
month = f"{date.month:02d}"
|
|
1198
1325
|
year = f"{date.year:,}".replace(",", ".")
|
|
1199
|
-
return f"{day}/{month}/{year}"
|
|
1326
|
+
return f"{day}/{month}/{year}"
|
|
1327
|
+
|
|
1328
|
+
def format_html(expression):
|
|
1329
|
+
html_expression = expression
|
|
1330
|
+
html_expression = re.sub(r"\\frac\{(.*?)\}\{(.*?)\}", r"<span style='font-size:90%;'>\1⁄\2</span>", html_expression)
|
|
1331
|
+
html_expression = re.sub(r"_\{([^}]+)\}", r"<sub>\1</sub>", html_expression)
|
|
1332
|
+
html_expression = re.sub(r"\^\{([^}]+)\}", r"<sup>\1</sup>", html_expression)
|
|
1333
|
+
html_expression = re.sub(r"_([a-zA-Z0-9]+)", r"<sub>\1</sub>", html_expression)
|
|
1334
|
+
html_expression = re.sub(r"\^([a-zA-Z0-9]+)", r"<sup>\1</sup>", html_expression)
|
|
1335
|
+
html_expression = html_expression.replace(" ", " ")
|
|
1336
|
+
return html_expression
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|