jbqt 0.1.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.
Potentially problematic release.
This version of jbqt might be problematic. Click here for more details.
- jbqt/__init__.py +0 -0
- jbqt/common/__init__.py +6 -0
- jbqt/common/consts.py +167 -0
- jbqt/common/qt_utils.py +81 -0
- jbqt/dialogs/__init__.py +7 -0
- jbqt/dialogs/file_dialog.py +27 -0
- jbqt/dialogs/input_form.py +85 -0
- jbqt/dialogs/text_preview.py +42 -0
- jbqt/models/__init__.py +6 -0
- jbqt/models/chip_button.py +13 -0
- jbqt/models/chips.py +31 -0
- jbqt/view_icons.py +208 -0
- jbqt/widgets/__init__.py +16 -0
- jbqt/widgets/chip_button.py +204 -0
- jbqt/widgets/chips.py +232 -0
- jbqt/widgets/multiselect.py +201 -0
- jbqt/widgets/simple.py +67 -0
- jbqt/widgets/toast.py +35 -0
- jbqt/widgets/widget_utils.py +77 -0
- jbqt-0.1.1.dist-info/METADATA +16 -0
- jbqt-0.1.1.dist-info/RECORD +22 -0
- jbqt-0.1.1.dist-info/WHEEL +4 -0
jbqt/widgets/simple.py
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
from PyQt6.QtCore import pyqtSignal, Qt, QObject, QEvent
|
|
4
|
+
from PyQt6.QtGui import QKeyEvent
|
|
5
|
+
from PyQt6.QtWidgets import QLabel, QLineEdit
|
|
6
|
+
|
|
7
|
+
NUM_RE = re.compile(r"^[-0-9]\d*$")
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ClickableLabel(QLabel):
|
|
11
|
+
clicked = pyqtSignal()
|
|
12
|
+
|
|
13
|
+
def __init__(self, text="", parent=None):
|
|
14
|
+
super().__init__(text, parent)
|
|
15
|
+
self.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
16
|
+
|
|
17
|
+
def mousePressEvent(self, event):
|
|
18
|
+
self.clicked.emit()
|
|
19
|
+
super().mousePressEvent(event)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def is_valid_key(event: QKeyEvent) -> bool:
|
|
23
|
+
if event.key() in [
|
|
24
|
+
Qt.Key.Key_0,
|
|
25
|
+
Qt.Key.Key_1,
|
|
26
|
+
Qt.Key.Key_2,
|
|
27
|
+
Qt.Key.Key_3,
|
|
28
|
+
Qt.Key.Key_4,
|
|
29
|
+
Qt.Key.Key_5,
|
|
30
|
+
Qt.Key.Key_6,
|
|
31
|
+
Qt.Key.Key_7,
|
|
32
|
+
Qt.Key.Key_8,
|
|
33
|
+
Qt.Key.Key_9,
|
|
34
|
+
Qt.Key.Key_Backspace,
|
|
35
|
+
]:
|
|
36
|
+
return True
|
|
37
|
+
|
|
38
|
+
if event.keyCombination().keyboardModifiers().name == "ControlModifier":
|
|
39
|
+
return True
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class LongIntSpinBox(QLineEdit):
|
|
43
|
+
valueChanged = pyqtSignal(int)
|
|
44
|
+
|
|
45
|
+
def __init__(self, parent=None) -> None:
|
|
46
|
+
super().__init__(parent)
|
|
47
|
+
self.installEventFilter(self)
|
|
48
|
+
self._value = 0
|
|
49
|
+
self.textChanged.connect(self.update_value)
|
|
50
|
+
|
|
51
|
+
def update_value(self, *_) -> None:
|
|
52
|
+
self.valueChanged.emit(self.value())
|
|
53
|
+
|
|
54
|
+
def setValue(self, value: int) -> None:
|
|
55
|
+
if value != self.value():
|
|
56
|
+
self.setText(str(value))
|
|
57
|
+
|
|
58
|
+
def value(self) -> int:
|
|
59
|
+
text = self.text()
|
|
60
|
+
if NUM_RE.match(text):
|
|
61
|
+
return int(text)
|
|
62
|
+
|
|
63
|
+
def eventFilter(self, obj: QObject, event: QKeyEvent) -> bool:
|
|
64
|
+
if event.type() == QEvent.Type.KeyPress:
|
|
65
|
+
if not is_valid_key(event):
|
|
66
|
+
return True
|
|
67
|
+
return super().eventFilter(obj, event)
|
jbqt/widgets/toast.py
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from PyQt6.QtCore import Qt, QTimer, QRect
|
|
2
|
+
from PyQt6.QtWidgets import QLabel
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Toast(QLabel):
|
|
6
|
+
def __init__(self, message, duration=2000):
|
|
7
|
+
super().__init__(message)
|
|
8
|
+
|
|
9
|
+
# Set the basic appearance
|
|
10
|
+
self.setWindowFlags(
|
|
11
|
+
Qt.WindowType.FramelessWindowHint | Qt.WindowType.ToolTip
|
|
12
|
+
)
|
|
13
|
+
self.setAttribute(Qt.WidgetAttribute.WA_TransparentForMouseEvents, True)
|
|
14
|
+
self.setStyleSheet(
|
|
15
|
+
"background-color: black; color: white; padding: 10px; border-radius: 5px;"
|
|
16
|
+
)
|
|
17
|
+
self.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
18
|
+
|
|
19
|
+
# Set the duration for the toast
|
|
20
|
+
self.timer = QTimer(self)
|
|
21
|
+
self.timer.timeout.connect(self.hide)
|
|
22
|
+
self.timer.setInterval(duration)
|
|
23
|
+
|
|
24
|
+
def show_toast(self, parent):
|
|
25
|
+
self.setParent(parent)
|
|
26
|
+
self.adjustSize()
|
|
27
|
+
|
|
28
|
+
# Center the toast in the parent widget
|
|
29
|
+
parent_rect: QRect = parent.rect()
|
|
30
|
+
move_point = parent_rect.center() - self.rect().center()
|
|
31
|
+
move_point.setY(20)
|
|
32
|
+
self.move(move_point)
|
|
33
|
+
# self.move((parent_rect.center() / 2) - self.rect().center())
|
|
34
|
+
self.show()
|
|
35
|
+
self.timer.start()
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
|
|
3
|
+
from jbqt.common.consts import GlobalRefs
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def debug_scroll_pos(func: Callable):
|
|
7
|
+
def wrapper(self, *args, **kwargs):
|
|
8
|
+
if GlobalRefs.scroll_area is None:
|
|
9
|
+
return func(self, *args, **kwargs)
|
|
10
|
+
focus = None
|
|
11
|
+
if GlobalRefs.main_window:
|
|
12
|
+
focus = GlobalRefs.main_window.focusWidget()
|
|
13
|
+
print(f"scroll pos {func.__name__}")
|
|
14
|
+
print("before", GlobalRefs.scroll_area.verticalScrollBar().value(), focus)
|
|
15
|
+
result = func(self, *args, **kwargs)
|
|
16
|
+
|
|
17
|
+
if GlobalRefs.main_window:
|
|
18
|
+
focus = GlobalRefs.main_window.focusWidget()
|
|
19
|
+
print(
|
|
20
|
+
f"after {GlobalRefs.scroll_area.verticalScrollBar().value()} {focus}\n"
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
return result
|
|
24
|
+
|
|
25
|
+
return wrapper
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def debug_scroll_pos_no_args(func: Callable):
|
|
29
|
+
def wrapper(self):
|
|
30
|
+
if GlobalRefs.scroll_area is None:
|
|
31
|
+
return func(self)
|
|
32
|
+
focus = None
|
|
33
|
+
if GlobalRefs.main_window:
|
|
34
|
+
focus = GlobalRefs.main_window.focusWidget()
|
|
35
|
+
print(f"scroll pos {func.__name__}")
|
|
36
|
+
print("before", GlobalRefs.scroll_area.verticalScrollBar().value(), focus)
|
|
37
|
+
result = func(self)
|
|
38
|
+
if GlobalRefs.main_window:
|
|
39
|
+
focus = GlobalRefs.main_window.focusWidget()
|
|
40
|
+
print(
|
|
41
|
+
f"after {GlobalRefs.scroll_area.verticalScrollBar().value()} {focus}\n"
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
return result
|
|
45
|
+
|
|
46
|
+
return wrapper
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _call_func(func: Callable, *args, **kwargs):
|
|
50
|
+
if args and kwargs:
|
|
51
|
+
return func(*args, **kwargs)
|
|
52
|
+
elif args:
|
|
53
|
+
return func(*args)
|
|
54
|
+
elif kwargs:
|
|
55
|
+
return func(**kwargs)
|
|
56
|
+
else:
|
|
57
|
+
return func()
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def preserve_scroll(func: Callable):
|
|
61
|
+
def wrapper(self, *args, **kwargs):
|
|
62
|
+
if GlobalRefs.scroll_area is None:
|
|
63
|
+
return _call_func(func, self, *args, **kwargs)
|
|
64
|
+
|
|
65
|
+
scroll_pos = GlobalRefs.scroll_area.verticalScrollBar().value()
|
|
66
|
+
focus = GlobalRefs.app.focusWidget()
|
|
67
|
+
result = _call_func(
|
|
68
|
+
func,
|
|
69
|
+
self,
|
|
70
|
+
*args,
|
|
71
|
+
**kwargs,
|
|
72
|
+
)
|
|
73
|
+
GlobalRefs.scroll_area.verticalScrollBar().setValue(scroll_pos)
|
|
74
|
+
focus.setFocus()
|
|
75
|
+
return result
|
|
76
|
+
|
|
77
|
+
return wrapper
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: jbqt
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary:
|
|
5
|
+
Author: Joseph Bochinski
|
|
6
|
+
Author-email: stirgejr@gmail.com
|
|
7
|
+
Requires-Python: >=3.12,<4.0
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
10
|
+
Requires-Dist: fuzzywuzzy (>=0.18.0,<0.19.0)
|
|
11
|
+
Requires-Dist: jb-utils (>=0.1.2,<0.2.0)
|
|
12
|
+
Requires-Dist: pyqt6 (>=6.9.0,<7.0.0)
|
|
13
|
+
Requires-Dist: python-levenshtein (>=0.27.1,<0.28.0)
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
jbqt/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
jbqt/common/__init__.py,sha256=zW8Bre-RNMnwQs9IIAhVygK12D2Hp3lu5wLRrg-AYvE,219
|
|
3
|
+
jbqt/common/consts.py,sha256=Nr_Y4oV46HKIEHDNDC9Ms8_rG7phYnjfCeqNqpFDvNU,5602
|
|
4
|
+
jbqt/common/qt_utils.py,sha256=d81MXUIs7JTpXOaPIoGHTLZYwhry7xhCWRy9BxitlzA,2297
|
|
5
|
+
jbqt/dialogs/__init__.py,sha256=DZi-qwW75JKfTLk33bowjt9Nhn1mpOO6kmP7mSMGz0o,245
|
|
6
|
+
jbqt/dialogs/file_dialog.py,sha256=xBUaxykAe3ajLJRgmykViKxTWyGfLIWJrfW4M8RP2lY,969
|
|
7
|
+
jbqt/dialogs/input_form.py,sha256=h4lzr4gv0PJTn0I77hdm_UIGeTng-buIuwzBSuswGxs,2451
|
|
8
|
+
jbqt/dialogs/text_preview.py,sha256=5rZjMvvMPq0jenPQkxKTFsGzuebdH_EnjKsdgNzv93o,1244
|
|
9
|
+
jbqt/models/__init__.py,sha256=aQUYSr2bL9uRVdmEh_3s5pHbzM0MyKXEiO2Bqe16I8A,155
|
|
10
|
+
jbqt/models/chip_button.py,sha256=nV5hVaYKStTOTGEa0WnVi1FolxrjnLQ1E3cSCQx-YkA,283
|
|
11
|
+
jbqt/models/chips.py,sha256=ou9RJxDSm6MI10CDnWrNi1DTRMKfqIIEowLVbyoFJZg,652
|
|
12
|
+
jbqt/view_icons.py,sha256=dwAAtDbqs3mwtmUxsjlFYdTsD2mi5m9BRmBQm6HpU9E,6389
|
|
13
|
+
jbqt/widgets/__init__.py,sha256=SBq_n_iVaRBPaav_sPsemrNT3yjh8zcQnhaRRbv4y8k,420
|
|
14
|
+
jbqt/widgets/chip_button.py,sha256=w_slazW-a4qmQDmdqSwtuPXLqA8rntjgHK3Tvgu3fDg,6222
|
|
15
|
+
jbqt/widgets/chips.py,sha256=zQ-UjrdZFARzPA18eJ5c5HcUHc1MyKNHdLfQUHma0LA,7744
|
|
16
|
+
jbqt/widgets/multiselect.py,sha256=_0Yt9SOjBsscHm10Lit3vtYFE7hrFSgFFa7kcDt3aAw,6982
|
|
17
|
+
jbqt/widgets/simple.py,sha256=-JVvNYiL05Ip7qSkt9rRFbdb-Jff6AbnuXPXOXdXoUw,1750
|
|
18
|
+
jbqt/widgets/toast.py,sha256=S85PgcydbmICnjSY5VR6KUG_UZv4UERjvE_mP_zE9GA,1179
|
|
19
|
+
jbqt/widgets/widget_utils.py,sha256=W8HkKJvTjGOB6wRR2D1sFzd673yEpPHNn-njjkM-1HE,2225
|
|
20
|
+
jbqt-0.1.1.dist-info/METADATA,sha256=Ais36vQZSHN7ndeV7784-RKYdNFAJFRruz7hvg_ml0k,463
|
|
21
|
+
jbqt-0.1.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
22
|
+
jbqt-0.1.1.dist-info/RECORD,,
|