jbqt 0.1.16__py3-none-any.whl → 0.1.17__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/dialogs/__init__.py +3 -2
- jbqt/dialogs/input_form.py +105 -50
- jbqt/dialogs/single_input.py +85 -0
- jbqt/models/__init__.py +2 -0
- jbqt/models/dialog_options.py +28 -0
- {jbqt-0.1.16.dist-info → jbqt-0.1.17.dist-info}/METADATA +2 -2
- {jbqt-0.1.16.dist-info → jbqt-0.1.17.dist-info}/RECORD +8 -6
- {jbqt-0.1.16.dist-info → jbqt-0.1.17.dist-info}/WHEEL +0 -0
jbqt/dialogs/__init__.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"""jbqt Dialog exports"""
|
|
2
2
|
|
|
3
|
-
from jbqt.dialogs.input_form import
|
|
3
|
+
from jbqt.dialogs.input_form import InputFormDialog
|
|
4
|
+
from jbqt.dialogs.single_input import InputDialog
|
|
4
5
|
from jbqt.dialogs.text_preview import TextPreviewDialog
|
|
5
6
|
from jbqt.dialogs.file_dialog import JbFileDialog
|
|
6
7
|
|
|
7
|
-
__all__ = ["InputDialog", "TextPreviewDialog", "JbFileDialog"]
|
|
8
|
+
__all__ = ["InputDialog", "InputFormDialog", "TextPreviewDialog", "JbFileDialog"]
|
jbqt/dialogs/input_form.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
1
2
|
from typing import Any, Callable
|
|
2
3
|
|
|
3
4
|
from PyQt6.QtCore import pyqtSignal
|
|
@@ -5,81 +6,135 @@ from PyQt6.QtWidgets import (
|
|
|
5
6
|
QDialog,
|
|
6
7
|
QDialogButtonBox,
|
|
7
8
|
QDoubleSpinBox,
|
|
9
|
+
QHBoxLayout,
|
|
8
10
|
QLabel,
|
|
11
|
+
QLayout,
|
|
9
12
|
QLineEdit,
|
|
13
|
+
QPushButton,
|
|
10
14
|
QSpinBox,
|
|
11
15
|
QVBoxLayout,
|
|
16
|
+
QWidget,
|
|
12
17
|
)
|
|
13
18
|
|
|
19
|
+
from PyQt6 import QtWidgets
|
|
14
20
|
|
|
15
|
-
|
|
21
|
+
from jbqt.models import DialogOptions
|
|
16
22
|
|
|
17
23
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
24
|
+
def get_widget(name: str) -> QWidget | None:
|
|
25
|
+
widget: QWidget | None = None
|
|
26
|
+
if hasattr(QtWidgets, name):
|
|
27
|
+
widget = getattr(QtWidgets, name)
|
|
28
|
+
""" elif hasattr(widgets, name):
|
|
29
|
+
widget = getattr(widgets, name) """
|
|
21
30
|
|
|
22
|
-
|
|
31
|
+
if widget:
|
|
32
|
+
if not callable(widget):
|
|
33
|
+
return
|
|
34
|
+
|
|
35
|
+
widget = widget()
|
|
36
|
+
if isinstance(widget, QWidget):
|
|
37
|
+
return widget
|
|
38
|
+
return None
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def get_widget_val(widget: QWidget) -> str | int | float | None:
|
|
42
|
+
# Emit the custom signal with data when the dialog is accepted
|
|
43
|
+
value = None
|
|
44
|
+
if isinstance(widget, QLineEdit):
|
|
45
|
+
value = widget.text()
|
|
46
|
+
elif isinstance(widget, QSpinBox):
|
|
47
|
+
value = widget.value()
|
|
48
|
+
elif isinstance(widget, QDoubleSpinBox):
|
|
49
|
+
value = widget.value()
|
|
50
|
+
|
|
51
|
+
return value
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class InputFormDialog(QDialog):
|
|
55
|
+
"""reference value for external use"""
|
|
56
|
+
|
|
57
|
+
value = pyqtSignal(dict)
|
|
23
58
|
|
|
24
59
|
def __init__(
|
|
25
60
|
self,
|
|
26
61
|
parent=None,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
input_type: type = str,
|
|
30
|
-
**opts,
|
|
62
|
+
form_data: list[dict] | None = None,
|
|
63
|
+
opts: DialogOptions | None = None,
|
|
31
64
|
):
|
|
32
65
|
super().__init__(parent)
|
|
33
66
|
|
|
34
|
-
|
|
67
|
+
opts = opts or DialogOptions(title="Input")
|
|
68
|
+
opts.apply(self)
|
|
35
69
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
| QDialogButtonBox.StandardButton.Open
|
|
39
|
-
)
|
|
70
|
+
self.form_data: list[dict] = [obj.copy() for obj in form_data or []]
|
|
71
|
+
self.input_widgets: dict[str, QWidget] = {}
|
|
40
72
|
|
|
41
|
-
self.
|
|
42
|
-
self.
|
|
43
|
-
self.buttonBox.rejected.connect(self.reject)
|
|
73
|
+
self.main_layout = QVBoxLayout()
|
|
74
|
+
self.construct_widgets()
|
|
44
75
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
76
|
+
button_box = QHBoxLayout()
|
|
77
|
+
submit_btn = QPushButton("Submit", parent=self)
|
|
78
|
+
submit_btn.clicked.connect(self.submit)
|
|
48
79
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
self.input_widget = QLineEdit()
|
|
52
|
-
elif input_type is int:
|
|
53
|
-
self.input_widget = QSpinBox()
|
|
54
|
-
elif input_type is float:
|
|
55
|
-
self.input_widget = QDoubleSpinBox()
|
|
80
|
+
cancel_btn = QPushButton("Cancel", parent=self)
|
|
81
|
+
cancel_btn.clicked.connect(self.close)
|
|
56
82
|
|
|
57
|
-
|
|
83
|
+
button_box.addWidget(submit_btn)
|
|
84
|
+
button_box.addWidget(cancel_btn)
|
|
85
|
+
self.main_layout.addLayout(button_box)
|
|
58
86
|
|
|
59
|
-
|
|
60
|
-
layout.addWidget(self.buttonBox)
|
|
61
|
-
self.setLayout(layout)
|
|
87
|
+
self.setLayout(self.main_layout)
|
|
62
88
|
|
|
63
|
-
def
|
|
64
|
-
for
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
setter = getattr(self.input_widget, setter_key)
|
|
68
|
-
if setter:
|
|
69
|
-
setter(value)
|
|
89
|
+
def construct_widgets(self) -> None:
|
|
90
|
+
for widget_def in self.form_data:
|
|
91
|
+
if not "type" in widget_def:
|
|
92
|
+
continue
|
|
70
93
|
|
|
71
|
-
|
|
72
|
-
for parm_type in self.signal_types:
|
|
73
|
-
self.value[parm_type].connect(callback)
|
|
94
|
+
layout = QHBoxLayout()
|
|
74
95
|
|
|
75
|
-
|
|
76
|
-
|
|
96
|
+
w_type = widget_def.pop("type")
|
|
97
|
+
label = widget_def.pop("label", "")
|
|
98
|
+
key = widget_def.pop("key", "")
|
|
99
|
+
if not key:
|
|
100
|
+
continue
|
|
77
101
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
self.value[float].emit(self.input_widget.value())
|
|
102
|
+
widget = get_widget(w_type)
|
|
103
|
+
if not widget:
|
|
104
|
+
continue
|
|
105
|
+
if label and isinstance(label, str):
|
|
106
|
+
layout.addWidget(QLabel(label))
|
|
84
107
|
|
|
85
|
-
|
|
108
|
+
if widget_def:
|
|
109
|
+
self._init_widget(widget, **widget_def)
|
|
110
|
+
layout.addWidget(widget)
|
|
111
|
+
self.main_layout.addLayout(layout)
|
|
112
|
+
self.input_widgets[key] = widget
|
|
113
|
+
|
|
114
|
+
def get_form_data(self) -> dict:
|
|
115
|
+
form_values: dict[str, Any] = {}
|
|
116
|
+
|
|
117
|
+
for key, widget in self.input_widgets.items():
|
|
118
|
+
value = get_widget_val(widget)
|
|
119
|
+
if value:
|
|
120
|
+
form_values[key] = value
|
|
121
|
+
|
|
122
|
+
return form_values
|
|
123
|
+
|
|
124
|
+
def submit(self) -> None:
|
|
125
|
+
form_data = self.get_form_data()
|
|
126
|
+
self.value.emit(form_data)
|
|
127
|
+
self.close()
|
|
128
|
+
|
|
129
|
+
def close(self) -> bool:
|
|
130
|
+
self.deleteLater()
|
|
131
|
+
|
|
132
|
+
return super().close()
|
|
133
|
+
|
|
134
|
+
def _init_widget(self, widget: QWidget, **opts) -> None:
|
|
135
|
+
for key, value in opts.items():
|
|
136
|
+
setter_key = f"set{key[0].upper() + key[1:]}"
|
|
137
|
+
if hasattr(widget, setter_key):
|
|
138
|
+
setter = getattr(widget, setter_key)
|
|
139
|
+
if setter:
|
|
140
|
+
setter(value)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
from typing import Any, Callable
|
|
2
|
+
|
|
3
|
+
from PyQt6.QtCore import pyqtSignal
|
|
4
|
+
from PyQt6.QtWidgets import (
|
|
5
|
+
QDialog,
|
|
6
|
+
QDialogButtonBox,
|
|
7
|
+
QDoubleSpinBox,
|
|
8
|
+
QLabel,
|
|
9
|
+
QLineEdit,
|
|
10
|
+
QSpinBox,
|
|
11
|
+
QVBoxLayout,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
INPUT_SIGNAL_TYPES: tuple[Any, ...] = (str, int, float)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class InputDialog(QDialog):
|
|
19
|
+
signal_types: tuple[Any] = INPUT_SIGNAL_TYPES
|
|
20
|
+
""" reference value for external use """
|
|
21
|
+
|
|
22
|
+
value = pyqtSignal(*([ptype] for ptype in INPUT_SIGNAL_TYPES))
|
|
23
|
+
|
|
24
|
+
def __init__(
|
|
25
|
+
self,
|
|
26
|
+
parent=None,
|
|
27
|
+
title: str = "Input",
|
|
28
|
+
msg_str: str = "Enter Input:",
|
|
29
|
+
input_type: type = str,
|
|
30
|
+
**opts,
|
|
31
|
+
):
|
|
32
|
+
super().__init__(parent)
|
|
33
|
+
|
|
34
|
+
self.setWindowTitle(title)
|
|
35
|
+
|
|
36
|
+
QBtn = (
|
|
37
|
+
QDialogButtonBox.StandardButton.Cancel
|
|
38
|
+
| QDialogButtonBox.StandardButton.Open
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
self.buttonBox = QDialogButtonBox(QBtn)
|
|
42
|
+
self.buttonBox.accepted.connect(self.accept)
|
|
43
|
+
self.buttonBox.rejected.connect(self.reject)
|
|
44
|
+
|
|
45
|
+
layout = QVBoxLayout()
|
|
46
|
+
message = QLabel(msg_str)
|
|
47
|
+
layout.addWidget(message)
|
|
48
|
+
|
|
49
|
+
self.input_widget = None
|
|
50
|
+
if input_type is str:
|
|
51
|
+
self.input_widget = QLineEdit()
|
|
52
|
+
elif input_type is int:
|
|
53
|
+
self.input_widget = QSpinBox()
|
|
54
|
+
elif input_type is float:
|
|
55
|
+
self.input_widget = QDoubleSpinBox()
|
|
56
|
+
|
|
57
|
+
self._init_widget(**opts)
|
|
58
|
+
|
|
59
|
+
layout.addWidget(self.input_widget)
|
|
60
|
+
layout.addWidget(self.buttonBox)
|
|
61
|
+
self.setLayout(layout)
|
|
62
|
+
|
|
63
|
+
def _init_widget(self, **opts) -> None:
|
|
64
|
+
for key, value in opts.items():
|
|
65
|
+
setter_key = f"set{key[0].upper() + key[1:]}"
|
|
66
|
+
if hasattr(self.input_widget, setter_key):
|
|
67
|
+
setter = getattr(self.input_widget, setter_key)
|
|
68
|
+
if setter:
|
|
69
|
+
setter(value)
|
|
70
|
+
|
|
71
|
+
def connect(self, callback: Callable) -> None:
|
|
72
|
+
for parm_type in self.signal_types:
|
|
73
|
+
self.value[parm_type].connect(callback)
|
|
74
|
+
|
|
75
|
+
def accept(self):
|
|
76
|
+
# Emit the custom signal with data when the dialog is accepted
|
|
77
|
+
|
|
78
|
+
if isinstance(self.input_widget, QLineEdit):
|
|
79
|
+
self.value[str].emit(self.input_widget.text())
|
|
80
|
+
elif isinstance(self.input_widget, QSpinBox):
|
|
81
|
+
self.value[int].emit(self.input_widget.value())
|
|
82
|
+
elif isinstance(self.input_widget, QDoubleSpinBox):
|
|
83
|
+
self.value[float].emit(self.input_widget.value())
|
|
84
|
+
|
|
85
|
+
super().accept()
|
jbqt/models/__init__.py
CHANGED
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
from jbqt.models.chips import IChipsWidget
|
|
4
4
|
from jbqt.models.chip_button import IChipButton
|
|
5
|
+
from jbqt.models.dialog_options import DialogOptions
|
|
5
6
|
from jbqt.models.model_consts import RegisteredFunctions
|
|
6
7
|
from jbqt.models.model_utils import get_fct, register_fct
|
|
7
8
|
from jbqt.models.toolbar_button import ToolbarButton
|
|
8
9
|
|
|
9
10
|
__all__ = [
|
|
11
|
+
"DialogOptions",
|
|
10
12
|
"get_fct",
|
|
11
13
|
"IChipButton",
|
|
12
14
|
"IChipsWidget",
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from PyQt6.QtCore import QObject
|
|
4
|
+
from PyQt6.QtWidgets import QWidget, QMainWindow, QApplication, QDialog
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class DialogOptions:
|
|
9
|
+
title: str = ""
|
|
10
|
+
x_pos: int | None = None
|
|
11
|
+
y_pos: int | None = None
|
|
12
|
+
height: int | None = None
|
|
13
|
+
width: int | None = None
|
|
14
|
+
|
|
15
|
+
def apply(self, q_obj: QWidget | QMainWindow | QDialog):
|
|
16
|
+
if self.title:
|
|
17
|
+
q_obj.setWindowTitle(self.title)
|
|
18
|
+
|
|
19
|
+
h, w, x, y = self.height, self.width, self.x_pos, self.y_pos
|
|
20
|
+
if h or w:
|
|
21
|
+
h = h or 400
|
|
22
|
+
w = w or 400
|
|
23
|
+
q_obj.resize(w, h)
|
|
24
|
+
|
|
25
|
+
if x is not None or y is not None:
|
|
26
|
+
x = x or 0
|
|
27
|
+
y = y or 0
|
|
28
|
+
q_obj.move(x, y)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: jbqt
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.17
|
|
4
4
|
Summary:
|
|
5
5
|
Author: Joseph Bochinski
|
|
6
6
|
Author-email: stirgejr@gmail.com
|
|
@@ -9,7 +9,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.12
|
|
10
10
|
Requires-Dist: fuzzywuzzy (>=0.18.0,<0.19.0)
|
|
11
11
|
Requires-Dist: jbconsts (>=0.1.1,<0.2.0)
|
|
12
|
-
Requires-Dist: jbutils (>=0.1.
|
|
12
|
+
Requires-Dist: jbutils (>=0.1.24,<0.2.0)
|
|
13
13
|
Requires-Dist: pyqt6 (>=6.9.0,<7.0.0)
|
|
14
14
|
Requires-Dist: python-levenshtein (>=0.27.1,<0.28.0)
|
|
15
15
|
Requires-Dist: rich (>=14.0.0,<15.0.0)
|
|
@@ -2,13 +2,15 @@ jbqt/__init__.py,sha256=qGE1sO5jh_hT3pr4AQQBKELiPxqSFna__j8u-sJz2nU,161
|
|
|
2
2
|
jbqt/common/__init__.py,sha256=knxf7Rc2gEN9qjWgZQdSu8oIznNlR6Z8D4zD_KU3UCE,151
|
|
3
3
|
jbqt/common/qt_utils.py,sha256=ag_CJfEQK-xFg8PvX6m4A5GplMjcRKFVCledVQVF9CA,2300
|
|
4
4
|
jbqt/consts/__init__.py,sha256=J2-z6t848A-FzSiZ7sASONSKn9Zn7VOSIphMNhv9zTE,6018
|
|
5
|
-
jbqt/dialogs/__init__.py,sha256=
|
|
5
|
+
jbqt/dialogs/__init__.py,sha256=8FBzE6e-0rupN4ODzNpTHHJZxfKGyciLIfYWSEKSrGs,318
|
|
6
6
|
jbqt/dialogs/file_dialog.py,sha256=QMUxgSNt1IGLqgPgKqrEwlPjKIQ7D5qrY2cJCXmW654,1830
|
|
7
|
-
jbqt/dialogs/input_form.py,sha256=
|
|
7
|
+
jbqt/dialogs/input_form.py,sha256=VYq8DRqMb3ZEOhyCl6NH_TssU8ekCVUxnTm75No7xSM,3741
|
|
8
|
+
jbqt/dialogs/single_input.py,sha256=pJVuP5fYc9USiwLmaSm66hrr-iW8XeZSY3eqxIUnVd0,2456
|
|
8
9
|
jbqt/dialogs/text_preview.py,sha256=5rZjMvvMPq0jenPQkxKTFsGzuebdH_EnjKsdgNzv93o,1244
|
|
9
|
-
jbqt/models/__init__.py,sha256=
|
|
10
|
+
jbqt/models/__init__.py,sha256=ZftJAf2S8rqoN1o_pJ2yYAhoENnKsofttt64b1kYxdE,491
|
|
10
11
|
jbqt/models/chip_button.py,sha256=lG76aNgnrZcSw5QzAJ6UUHMbNNkDI-yZAp3iJlKr0Ms,220
|
|
11
12
|
jbqt/models/chips.py,sha256=Qil50f1DcmYDHxiQgf0qs0kqERb-PTH37eOLHCuWA2o,625
|
|
13
|
+
jbqt/models/dialog_options.py,sha256=r3_0eVC3swrfUcbaV2mTXszuoBs4mbFK9r5okHB3boE,730
|
|
12
14
|
jbqt/models/model_consts.py,sha256=84xPj4RNCGib7d4dBOOybzD3z0_uav37jrzqGfZkAQ8,170
|
|
13
15
|
jbqt/models/model_utils.py,sha256=Tf8QwJKHj3vpAkSTn-qP3XdihKnPqJvr5gq2c-8cCJM,809
|
|
14
16
|
jbqt/models/toolbar_button.py,sha256=5jQisgsFaQ7_b0D-bV9jiHDIMOO6-j_H8qgA2Qdn7NU,1736
|
|
@@ -21,6 +23,6 @@ jbqt/widgets/multiselect.py,sha256=ucL6QeFHs12DnHAHASMwdOD9YFYu4x4NDCYa6Pl41HM,7
|
|
|
21
23
|
jbqt/widgets/simple.py,sha256=pj2PBdR1am7VtPi4jGxsKm5nOLyTwiZV4jCuTd58rpk,1841
|
|
22
24
|
jbqt/widgets/toast.py,sha256=S85PgcydbmICnjSY5VR6KUG_UZv4UERjvE_mP_zE9GA,1179
|
|
23
25
|
jbqt/widgets/widget_utils.py,sha256=IEVg60rJ6hL0_9wre7j-_aprg-fccNZhwwOtbVEmHvw,2525
|
|
24
|
-
jbqt-0.1.
|
|
25
|
-
jbqt-0.1.
|
|
26
|
-
jbqt-0.1.
|
|
26
|
+
jbqt-0.1.17.dist-info/METADATA,sha256=CPidysbyPX4q5TYg6oreR8I6oaW0fbOpc1yt6tDRSo0,544
|
|
27
|
+
jbqt-0.1.17.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
28
|
+
jbqt-0.1.17.dist-info/RECORD,,
|
|
File without changes
|