sciwidgets 0.1.2__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.
Files changed (35) hide show
  1. sciwidgets-0.1.2/LICENSE +21 -0
  2. sciwidgets-0.1.2/PKG-INFO +173 -0
  3. sciwidgets-0.1.2/README.md +142 -0
  4. sciwidgets-0.1.2/pyproject.toml +48 -0
  5. sciwidgets-0.1.2/setup.cfg +4 -0
  6. sciwidgets-0.1.2/src/sciwidgets/__init__.py +8 -0
  7. sciwidgets-0.1.2/src/sciwidgets/dialogs/__init__.py +31 -0
  8. sciwidgets-0.1.2/src/sciwidgets/dialogs/__main__.py +128 -0
  9. sciwidgets-0.1.2/src/sciwidgets/dialogs/message_dialogs.py +553 -0
  10. sciwidgets-0.1.2/src/sciwidgets/formatting.py +161 -0
  11. sciwidgets-0.1.2/src/sciwidgets/labels/__init__.py +3 -0
  12. sciwidgets-0.1.2/src/sciwidgets/labels/__main__.py +124 -0
  13. sciwidgets-0.1.2/src/sciwidgets/labels/math_label.py +505 -0
  14. sciwidgets-0.1.2/src/sciwidgets/params/__init__.py +18 -0
  15. sciwidgets-0.1.2/src/sciwidgets/params/__main__.py +81 -0
  16. sciwidgets-0.1.2/src/sciwidgets/params/base.py +220 -0
  17. sciwidgets-0.1.2/src/sciwidgets/params/combo_box.py +106 -0
  18. sciwidgets-0.1.2/src/sciwidgets/params/line_edit.py +132 -0
  19. sciwidgets-0.1.2/src/sciwidgets/params/numeric_line_edit.py +680 -0
  20. sciwidgets-0.1.2/src/sciwidgets/params/sliders/__init__.py +36 -0
  21. sciwidgets-0.1.2/src/sciwidgets/params/sliders/__main__.py +215 -0
  22. sciwidgets-0.1.2/src/sciwidgets/params/sliders/_defaults.py +36 -0
  23. sciwidgets-0.1.2/src/sciwidgets/params/sliders/_dialogs.py +174 -0
  24. sciwidgets-0.1.2/src/sciwidgets/params/sliders/_right_click_overlay.py +115 -0
  25. sciwidgets-0.1.2/src/sciwidgets/params/sliders/base.py +592 -0
  26. sciwidgets-0.1.2/src/sciwidgets/params/sliders/multi.py +660 -0
  27. sciwidgets-0.1.2/src/sciwidgets/params/sliders/range.py +1841 -0
  28. sciwidgets-0.1.2/src/sciwidgets/params/sliders/single.py +2042 -0
  29. sciwidgets-0.1.2/src/sciwidgets/params/toggle.py +116 -0
  30. sciwidgets-0.1.2/src/sciwidgets/style.py +175 -0
  31. sciwidgets-0.1.2/src/sciwidgets.egg-info/PKG-INFO +173 -0
  32. sciwidgets-0.1.2/src/sciwidgets.egg-info/SOURCES.txt +33 -0
  33. sciwidgets-0.1.2/src/sciwidgets.egg-info/dependency_links.txt +1 -0
  34. sciwidgets-0.1.2/src/sciwidgets.egg-info/requires.txt +7 -0
  35. sciwidgets-0.1.2/src/sciwidgets.egg-info/top_level.txt +1 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vahid Anari
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,173 @@
1
+ Metadata-Version: 2.4
2
+ Name: sciwidgets
3
+ Version: 0.1.2
4
+ Summary: PySide6 widgets for scientific desktop apps: math labels, sliders, parameter inputs and dialogs
5
+ Author-email: Vahid Anari <vahid.anari8@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/vahid-anari/sciwidgets
8
+ Project-URL: Repository, https://github.com/vahid-anari/sciwidgets
9
+ Project-URL: Issues, https://github.com/vahid-anari/sciwidgets/issues
10
+ Keywords: pyside6,qt,gui,widgets,scientific,slider,range-slider,latex,matplotlib,dialogs
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Scientific/Engineering
20
+ Classifier: Topic :: Software Development :: User Interfaces
21
+ Requires-Python: >=3.10
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: PySide6<7,>=6.5
25
+ Requires-Dist: matplotlib>=3.7
26
+ Requires-Dist: numpy>=1.24
27
+ Provides-Extra: dev
28
+ Requires-Dist: build; extra == "dev"
29
+ Requires-Dist: twine; extra == "dev"
30
+ Dynamic: license-file
31
+
32
+ # sciwidgets
33
+
34
+ PySide6 widgets for scientific desktop apps: math labels rendered with
35
+ LaTeX/mathtext, dialogs, and parameter inputs such as sliders, range sliders
36
+ and validated number fields.
37
+
38
+ ![Sliders demo](https://raw.githubusercontent.com/vahid-anari/sciwidgets/main/docs/images/sliders_demo.png)
39
+
40
+ Right-click menu, Set Value and Edit Configuration:
41
+
42
+ ![Slider interaction](https://raw.githubusercontent.com/vahid-anari/sciwidgets/main/docs/images/sliders_demo.gif)
43
+
44
+ The widgets were written for the
45
+ [Maxwell Bloch Solver](https://github.com/vahid-anari/maxwell-bloch-solver)
46
+ and moved into this package so other apps can share them.
47
+
48
+ ## Features
49
+
50
+ - **Math labels**: `MathLabel` renders LaTeX through Matplotlib and scales
51
+ cleanly as SVG. It uses your system LaTeX when installed and falls back to
52
+ Matplotlib's mathtext otherwise.
53
+ - **Sliders**: integer, float, array, range and multi-variable sliders with
54
+ LaTeX names and units, optional range labels, a default-value marker and a
55
+ right-click menu (save/reset default, set value, ±inf, edit range and format).
56
+ - **Scientific number format**: `"{:.3S}"` displays values as `1.23×10⁴`.
57
+ - **Validated input**: `NumericLineEdit` checks numbers and limits while typing
58
+ and marks invalid input with a red frame.
59
+ - **Parameter widgets**: line edit, combo box and toggle sharing one interface
60
+ with the sliders (`get_value` / `set_value`, `get_config` / `set_config`) and
61
+ name/value columns that line up across a panel.
62
+ - **Dialogs**: information, warning, error, question, rich-text and About
63
+ dialogs.
64
+
65
+ ## Components
66
+
67
+ | Import | Contents |
68
+ |--------|----------|
69
+ | `sciwidgets.labels` | `MathLabel` (LaTeX/mathtext label), `set_latex_enabled` |
70
+ | `sciwidgets.params` | `FloatSlider`, `IntSlider`, `ArraySlider`, `FloatRangeSlider`, `IntRangeSlider`, `MultiVariableSlider`, `ParameterLineEdit`, `ParameterComboBox`, `ParameterToggle`, `NumericLineEdit`, `SliderFeature` |
71
+ | `sciwidgets.dialogs` | `show_information`, `show_warning`, `show_critical`, `show_rich_information`, `show_about_dialog`, `ask_question`, `AskResult` |
72
+ | `sciwidgets.style` | `SciStyle`, `apply_sci_style`, `sci_style_sheet` |
73
+ | `sciwidgets.formatting` | `pretty_sci_text`, `value_to_text` and other format helpers |
74
+
75
+ ## Install
76
+
77
+ ```bash
78
+ pip install sciwidgets
79
+ ```
80
+
81
+ Requires Python 3.10+, PySide6 6.5+, Matplotlib and NumPy (installed
82
+ automatically). A LaTeX installation is optional.
83
+
84
+ For development, from the repo root:
85
+
86
+ ```bash
87
+ pip install -e .
88
+ ```
89
+
90
+ ## Quick start
91
+
92
+ ```python
93
+ import sys
94
+
95
+ from PySide6.QtWidgets import QApplication, QVBoxLayout, QWidget
96
+
97
+ from sciwidgets.params import FloatRangeSlider, FloatSlider
98
+ from sciwidgets.style import apply_sci_style
99
+
100
+ app = QApplication(sys.argv)
101
+ apply_sci_style(app) # required, see "Style" below
102
+
103
+ win = QWidget()
104
+ layout = QVBoxLayout(win)
105
+
106
+ t1 = FloatSlider(
107
+ label="T_1", unit=r"\mathrm{ms}",
108
+ min_val=0.1, max_val=10.0, init_val=1.0, val_fmt="{:.2f}",
109
+ min_limit=0.0, min_limit_inclusive=False,
110
+ )
111
+ band = FloatRangeSlider(
112
+ label=r"\nu", unit=r"\mathrm{GHz}",
113
+ min_val=6.60, max_val=6.75, init_vals=(6.65, 6.70), val_fmt="{:.3f}",
114
+ )
115
+ layout.addWidget(t1)
116
+ layout.addWidget(band)
117
+
118
+ t1.valueChanged.connect(lambda v: print("T1 =", v))
119
+ band.valueChanged.connect(lambda v: print("band =", v["range"]))
120
+
121
+ win.show()
122
+ sys.exit(app.exec())
123
+ ```
124
+
125
+ Labels and units are written in LaTeX math mode, without the `$` signs.
126
+
127
+ ## Style
128
+
129
+ The widgets rely on `SciStyle`, a Fusion-based Qt style, for part of their
130
+ behaviour: clicking a slider groove moves the handle there, disabled sliders
131
+ get a flat groove, and invalid numeric input gets a red frame. Apply it once
132
+ at startup:
133
+
134
+ ```python
135
+ from sciwidgets.style import apply_sci_style
136
+
137
+ apply_sci_style(app, my_app_style_sheet) # your own rules are appended
138
+ ```
139
+
140
+ ## Signals
141
+
142
+ `valueChanged`, `defaultChanged` and `configChanged` are emitted **only for
143
+ user actions** (dragging, typing, the context menu, dialogs). Setting values
144
+ from code with `set_value`, `set_config` and similar methods is silent, so
145
+ loading saved parameters never triggers your handlers. Read the new state
146
+ with `get_value()` / `get_config()` after setting it.
147
+
148
+ ## Demos
149
+
150
+ Each subpackage has a runnable demo:
151
+
152
+ ```bash
153
+ python -m sciwidgets.labels
154
+ python -m sciwidgets.dialogs
155
+ python -m sciwidgets.params
156
+ python -m sciwidgets.params.sliders
157
+ ```
158
+
159
+ ## Versions
160
+
161
+ Releases are Git tags following [semantic versioning](https://semver.org).
162
+ Pin an exact tag in your app's requirements, as in the install line above,
163
+ and move to a newer tag when you are ready to test it.
164
+
165
+ ## License
166
+
167
+ MIT License. See [LICENSE](https://github.com/vahid-anari/sciwidgets/blob/main/LICENSE).
168
+
169
+ ## Author
170
+
171
+ Vahid Anari ·
172
+ [GitHub](https://github.com/vahid-anari) ·
173
+ [LinkedIn](https://www.linkedin.com/in/vahid-anari/)
@@ -0,0 +1,142 @@
1
+ # sciwidgets
2
+
3
+ PySide6 widgets for scientific desktop apps: math labels rendered with
4
+ LaTeX/mathtext, dialogs, and parameter inputs such as sliders, range sliders
5
+ and validated number fields.
6
+
7
+ ![Sliders demo](https://raw.githubusercontent.com/vahid-anari/sciwidgets/main/docs/images/sliders_demo.png)
8
+
9
+ Right-click menu, Set Value and Edit Configuration:
10
+
11
+ ![Slider interaction](https://raw.githubusercontent.com/vahid-anari/sciwidgets/main/docs/images/sliders_demo.gif)
12
+
13
+ The widgets were written for the
14
+ [Maxwell Bloch Solver](https://github.com/vahid-anari/maxwell-bloch-solver)
15
+ and moved into this package so other apps can share them.
16
+
17
+ ## Features
18
+
19
+ - **Math labels**: `MathLabel` renders LaTeX through Matplotlib and scales
20
+ cleanly as SVG. It uses your system LaTeX when installed and falls back to
21
+ Matplotlib's mathtext otherwise.
22
+ - **Sliders**: integer, float, array, range and multi-variable sliders with
23
+ LaTeX names and units, optional range labels, a default-value marker and a
24
+ right-click menu (save/reset default, set value, ±inf, edit range and format).
25
+ - **Scientific number format**: `"{:.3S}"` displays values as `1.23×10⁴`.
26
+ - **Validated input**: `NumericLineEdit` checks numbers and limits while typing
27
+ and marks invalid input with a red frame.
28
+ - **Parameter widgets**: line edit, combo box and toggle sharing one interface
29
+ with the sliders (`get_value` / `set_value`, `get_config` / `set_config`) and
30
+ name/value columns that line up across a panel.
31
+ - **Dialogs**: information, warning, error, question, rich-text and About
32
+ dialogs.
33
+
34
+ ## Components
35
+
36
+ | Import | Contents |
37
+ |--------|----------|
38
+ | `sciwidgets.labels` | `MathLabel` (LaTeX/mathtext label), `set_latex_enabled` |
39
+ | `sciwidgets.params` | `FloatSlider`, `IntSlider`, `ArraySlider`, `FloatRangeSlider`, `IntRangeSlider`, `MultiVariableSlider`, `ParameterLineEdit`, `ParameterComboBox`, `ParameterToggle`, `NumericLineEdit`, `SliderFeature` |
40
+ | `sciwidgets.dialogs` | `show_information`, `show_warning`, `show_critical`, `show_rich_information`, `show_about_dialog`, `ask_question`, `AskResult` |
41
+ | `sciwidgets.style` | `SciStyle`, `apply_sci_style`, `sci_style_sheet` |
42
+ | `sciwidgets.formatting` | `pretty_sci_text`, `value_to_text` and other format helpers |
43
+
44
+ ## Install
45
+
46
+ ```bash
47
+ pip install sciwidgets
48
+ ```
49
+
50
+ Requires Python 3.10+, PySide6 6.5+, Matplotlib and NumPy (installed
51
+ automatically). A LaTeX installation is optional.
52
+
53
+ For development, from the repo root:
54
+
55
+ ```bash
56
+ pip install -e .
57
+ ```
58
+
59
+ ## Quick start
60
+
61
+ ```python
62
+ import sys
63
+
64
+ from PySide6.QtWidgets import QApplication, QVBoxLayout, QWidget
65
+
66
+ from sciwidgets.params import FloatRangeSlider, FloatSlider
67
+ from sciwidgets.style import apply_sci_style
68
+
69
+ app = QApplication(sys.argv)
70
+ apply_sci_style(app) # required, see "Style" below
71
+
72
+ win = QWidget()
73
+ layout = QVBoxLayout(win)
74
+
75
+ t1 = FloatSlider(
76
+ label="T_1", unit=r"\mathrm{ms}",
77
+ min_val=0.1, max_val=10.0, init_val=1.0, val_fmt="{:.2f}",
78
+ min_limit=0.0, min_limit_inclusive=False,
79
+ )
80
+ band = FloatRangeSlider(
81
+ label=r"\nu", unit=r"\mathrm{GHz}",
82
+ min_val=6.60, max_val=6.75, init_vals=(6.65, 6.70), val_fmt="{:.3f}",
83
+ )
84
+ layout.addWidget(t1)
85
+ layout.addWidget(band)
86
+
87
+ t1.valueChanged.connect(lambda v: print("T1 =", v))
88
+ band.valueChanged.connect(lambda v: print("band =", v["range"]))
89
+
90
+ win.show()
91
+ sys.exit(app.exec())
92
+ ```
93
+
94
+ Labels and units are written in LaTeX math mode, without the `$` signs.
95
+
96
+ ## Style
97
+
98
+ The widgets rely on `SciStyle`, a Fusion-based Qt style, for part of their
99
+ behaviour: clicking a slider groove moves the handle there, disabled sliders
100
+ get a flat groove, and invalid numeric input gets a red frame. Apply it once
101
+ at startup:
102
+
103
+ ```python
104
+ from sciwidgets.style import apply_sci_style
105
+
106
+ apply_sci_style(app, my_app_style_sheet) # your own rules are appended
107
+ ```
108
+
109
+ ## Signals
110
+
111
+ `valueChanged`, `defaultChanged` and `configChanged` are emitted **only for
112
+ user actions** (dragging, typing, the context menu, dialogs). Setting values
113
+ from code with `set_value`, `set_config` and similar methods is silent, so
114
+ loading saved parameters never triggers your handlers. Read the new state
115
+ with `get_value()` / `get_config()` after setting it.
116
+
117
+ ## Demos
118
+
119
+ Each subpackage has a runnable demo:
120
+
121
+ ```bash
122
+ python -m sciwidgets.labels
123
+ python -m sciwidgets.dialogs
124
+ python -m sciwidgets.params
125
+ python -m sciwidgets.params.sliders
126
+ ```
127
+
128
+ ## Versions
129
+
130
+ Releases are Git tags following [semantic versioning](https://semver.org).
131
+ Pin an exact tag in your app's requirements, as in the install line above,
132
+ and move to a newer tag when you are ready to test it.
133
+
134
+ ## License
135
+
136
+ MIT License. See [LICENSE](https://github.com/vahid-anari/sciwidgets/blob/main/LICENSE).
137
+
138
+ ## Author
139
+
140
+ Vahid Anari ·
141
+ [GitHub](https://github.com/vahid-anari) ·
142
+ [LinkedIn](https://www.linkedin.com/in/vahid-anari/)
@@ -0,0 +1,48 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "sciwidgets"
7
+ version = "0.1.2"
8
+ description = "PySide6 widgets for scientific desktop apps: math labels, sliders, parameter inputs and dialogs"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "Vahid Anari", email = "vahid.anari8@gmail.com" }]
14
+ keywords = [
15
+ "pyside6", "qt", "gui", "widgets", "scientific",
16
+ "slider", "range-slider", "latex", "matplotlib", "dialogs",
17
+ ]
18
+ classifiers = [
19
+ "Development Status :: 3 - Alpha",
20
+ "Intended Audience :: Science/Research",
21
+ "Intended Audience :: Developers",
22
+ "Operating System :: OS Independent",
23
+ "Programming Language :: Python :: 3",
24
+ "Programming Language :: Python :: 3.10",
25
+ "Programming Language :: Python :: 3.11",
26
+ "Programming Language :: Python :: 3.12",
27
+ "Topic :: Scientific/Engineering",
28
+ "Topic :: Software Development :: User Interfaces",
29
+ ]
30
+ dependencies = [
31
+ "PySide6>=6.5,<7",
32
+ "matplotlib>=3.7",
33
+ "numpy>=1.24",
34
+ ]
35
+
36
+ [project.optional-dependencies]
37
+ dev = ["build", "twine"]
38
+
39
+ [project.urls]
40
+ Homepage = "https://github.com/vahid-anari/sciwidgets"
41
+ Repository = "https://github.com/vahid-anari/sciwidgets"
42
+ Issues = "https://github.com/vahid-anari/sciwidgets/issues"
43
+
44
+ [tool.setuptools.packages.find]
45
+ where = ["src"]
46
+
47
+ [tool.setuptools.package-data]
48
+ "*" = ["*.svg", "*.png"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,8 @@
1
+ """PySide6 widgets for scientific desktop apps."""
2
+
3
+ from importlib.metadata import PackageNotFoundError, version
4
+
5
+ try:
6
+ __version__ = version("sciwidgets")
7
+ except PackageNotFoundError:
8
+ __version__ = "0+unknown"
@@ -0,0 +1,31 @@
1
+ from .message_dialogs import (
2
+ AboutDialog,
3
+ AskDialog,
4
+ AskResult,
5
+ DialogIcon,
6
+ InfoDialog,
7
+ MessageDialog,
8
+ TitledDialogBase,
9
+ ask_question,
10
+ show_about_dialog,
11
+ show_critical,
12
+ show_information,
13
+ show_rich_information,
14
+ show_warning,
15
+ )
16
+
17
+ __all__ = [
18
+ "AboutDialog",
19
+ "AskDialog",
20
+ "AskResult",
21
+ "DialogIcon",
22
+ "InfoDialog",
23
+ "MessageDialog",
24
+ "TitledDialogBase",
25
+ "ask_question",
26
+ "show_about_dialog",
27
+ "show_critical",
28
+ "show_information",
29
+ "show_rich_information",
30
+ "show_warning",
31
+ ]
@@ -0,0 +1,128 @@
1
+ """Demo for the dialogs subpackage: ``python -m sciwidgets.dialogs``."""
2
+
3
+ import sys
4
+
5
+ from PySide6.QtWidgets import (
6
+ QApplication, QHBoxLayout, QPushButton, QStyle, QVBoxLayout, QWidget,
7
+ )
8
+
9
+ from sciwidgets.dialogs.message_dialogs import (
10
+ ask_question,
11
+ show_about_dialog,
12
+ show_critical,
13
+ show_information,
14
+ show_rich_information,
15
+ show_warning,
16
+ )
17
+
18
+
19
+ def _demo_main() -> int:
20
+ """Run a window with one button per dialog helper.
21
+
22
+ Returns:
23
+ int: Qt application exit code.
24
+ """
25
+ app = QApplication(sys.argv)
26
+ win = QWidget()
27
+ win.setWindowTitle("Dialogs demo")
28
+
29
+ # --- Questions --------------------------------------------------------
30
+ def ask_save() -> None:
31
+ r = ask_question(
32
+ "Unsaved Changes",
33
+ "Do you want to save your changes before closing?",
34
+ "Your modifications will be lost if you close without saving.",
35
+ yes_btn_label="Save", no_btn_label="Don't Save", parent=win,
36
+ )
37
+ print("ask (save):", r)
38
+
39
+ def ask_yes_no() -> None:
40
+ r = ask_question(
41
+ "Continue", "Do you want to continue?",
42
+ "Yes continues the operation.\nNo stops without changes.",
43
+ no_btn_label="No", parent=win,
44
+ )
45
+ print("ask (yes/no):", r)
46
+
47
+ def ask_two_buttons() -> None:
48
+ r = ask_question(
49
+ "Delete File", "Do you want to delete this file?",
50
+ "This action cannot be undone.",
51
+ yes_btn_label="Delete", parent=win,
52
+ )
53
+ print("ask (two buttons):", r)
54
+
55
+ # --- Messages ---------------------------------------------------------
56
+ def info() -> None:
57
+ show_information(
58
+ "Data Information", "The data file was loaded successfully.",
59
+ "128 rows were read and validated.\nNo missing values were found.",
60
+ parent=win,
61
+ )
62
+
63
+ def warning() -> None:
64
+ show_warning(
65
+ "Overwrite File", "A file with this name already exists.",
66
+ "Saving now will replace the existing file.", parent=win,
67
+ )
68
+
69
+ def critical() -> None:
70
+ show_critical(
71
+ "Load Error", "The selected file could not be opened.",
72
+ "Check that the file exists and that you can read it.", parent=win,
73
+ )
74
+
75
+ def rich_info() -> None:
76
+ show_rich_information(
77
+ "Notes",
78
+ "<b>Rich information dialog</b><br><br>"
79
+ "Useful for longer help text, with selectable text, a copy "
80
+ "button, and links: "
81
+ '<a href="https://doc.qt.io/qtforpython-6/">Qt for Python docs</a>',
82
+ parent=win,
83
+ )
84
+
85
+ # --- About ------------------------------------------------------------
86
+ about_html = (
87
+ "A demo application for <b>sciwidgets</b>.<br><br>"
88
+ "<b>Version:</b> 0.1.0<br>"
89
+ '<b>Docs:</b> <a href="https://doc.qt.io/qtforpython-6/">Qt for Python</a>'
90
+ )
91
+
92
+ def about_default() -> None:
93
+ # No app icon is set in this demo, so the information icon is used.
94
+ show_about_dialog("About Demo", about_html, parent=win)
95
+
96
+ def about_custom_icon() -> None:
97
+ icon = win.style().standardIcon(QStyle.SP_ComputerIcon)
98
+ show_about_dialog("About Demo", about_html, parent=win, icon=icon)
99
+
100
+ # --- Layout -----------------------------------------------------------
101
+ columns = [
102
+ [("Ask: Save / Don't Save / Cancel", ask_save),
103
+ ("Ask: Yes / No / Cancel", ask_yes_no),
104
+ ("Ask: Delete / Cancel", ask_two_buttons)],
105
+ [("Information", info),
106
+ ("Warning", warning),
107
+ ("Critical", critical),
108
+ ("Rich information", rich_info)],
109
+ [("About (default icon)", about_default),
110
+ ("About (custom icon)", about_custom_icon)],
111
+ ]
112
+
113
+ row = QHBoxLayout(win)
114
+ for buttons in columns:
115
+ col = QVBoxLayout()
116
+ for text, slot in buttons:
117
+ btn = QPushButton(text)
118
+ btn.clicked.connect(slot)
119
+ col.addWidget(btn)
120
+ col.addStretch(1)
121
+ row.addLayout(col)
122
+
123
+ win.show()
124
+ return app.exec()
125
+
126
+
127
+ if __name__ == "__main__":
128
+ raise SystemExit(_demo_main())