Metadata-Version: 2.4
Name: sciwidgets
Version: 0.11.0
Summary: PySide6 widgets for scientific desktop apps: LaTeX labels, sliders, parameter panels, Matplotlib plot canvas, DataFrame tables and dialogs
Author-email: Vahid Anari <vahid.anari8@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/vahid-anari/sciwidgets
Project-URL: Repository, https://github.com/vahid-anari/sciwidgets
Project-URL: Issues, https://github.com/vahid-anari/sciwidgets/issues
Keywords: pyside6,qt,gui,widgets,scientific,slider,range-slider,latex,matplotlib,dialogs,status-bar,menu
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Software Development :: User Interfaces
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: PySide6<7,>=6.5; python_version >= "3.12"
Requires-Dist: PySide6!=6.12.0,<7,>=6.5; python_version < "3.12"
Requires-Dist: matplotlib>=3.7
Requires-Dist: numpy>=1.24
Requires-Dist: psutil>=5.9
Provides-Extra: table
Requires-Dist: pandas>=2.0; extra == "table"
Provides-Extra: dev
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Requires-Dist: pytest; extra == "dev"
Requires-Dist: pandas>=2.0; extra == "dev"
Dynamic: license-file

# sciwidgets

[![tests](https://github.com/vahid-anari/sciwidgets/actions/workflows/tests.yml/badge.svg)](https://github.com/vahid-anari/sciwidgets/actions/workflows/tests.yml)
[![PyPI](https://img.shields.io/pypi/v/sciwidgets)](https://pypi.org/project/sciwidgets/)
[![Python](https://img.shields.io/pypi/pyversions/sciwidgets)](https://pypi.org/project/sciwidgets/)
![License](https://img.shields.io/badge/license-MIT-green)

PySide6 widgets for scientific desktop apps: math labels rendered with
LaTeX/mathtext, dialogs, and parameter inputs such as sliders, range sliders
and validated number fields.

<img src="https://raw.githubusercontent.com/vahid-anari/sciwidgets/main/docs/figures/sliders_demo.png" width="900" alt="Sliders demo">

Right-click menu, Set Value and Edit Configuration:

![Slider interaction](https://raw.githubusercontent.com/vahid-anari/sciwidgets/main/docs/figures/sliders_demo.gif)

The widgets were written for
[Maxwell Bloch Studio](https://github.com/vahid-anari/maxwell-bloch-studio)
and moved into this package so other apps can share them.

## Features

- **Math labels**: `MathLabel` renders LaTeX through Matplotlib and scales
  cleanly as SVG. It uses your system LaTeX when installed and falls back to
  Matplotlib's mathtext otherwise.
- **Sliders**: integer, float, array, range and multi-variable sliders with
  LaTeX names and units, optional range labels, a default-value marker and a
  right-click menu (save/reset default, set value, ±inf, edit range and format).
- **Scientific number format**: `"{:.3S}"` displays values as `1.23×10⁴`.
- **Validated input**: `NumericLineEdit` checks numbers and limits while typing
  and marks invalid input with a red frame.
- **Parameter widgets**: line edit, combo box and toggle sharing one interface
  with the sliders (`get_value` / `set_value`, `get_config` / `set_config`) and
  name/value columns that line up across a panel.
- **Parameter panels**: build groups, columns and tabs of parameter widgets
  from a JSON-style description, with templates and shared defaults, and read
  or restore all values as one dict.
- **Plot canvas**: Matplotlib panels, twins, legends and markers from a
  description; data by curve id; a right-click style menu for curves, grids
  and spans whose changes save as plain data.
- **Dialogs**: information, warning, error, question, rich-text and About
  dialogs.
- **Splash screen**: your picture with the app name and version drawn on it,
  sharp on Retina, and start-up messages from anywhere in the app.

## Components

| Import | Contents | Docs |
|--------|----------|------|
| `sciwidgets.params` (sliders) | `FloatSlider`, `IntSlider`, `ArraySlider`, `FloatRangeSlider`, `IntRangeSlider`, `MultiVariableSlider`, `SliderFeature` | [Sliders](https://github.com/vahid-anari/sciwidgets/blob/main/docs/sliders.md) |
| `sciwidgets.params` (inputs) | `ParameterLineEdit`, `ParameterComboBox`, `ParameterToggle`, `NumericLineEdit` | [Parameter widgets](https://github.com/vahid-anari/sciwidgets/blob/main/docs/params.md) |
| `sciwidgets.panel` | `ParameterPage`, `ParameterTabs`, `widget_from_spec`, `register_type` | [Parameter panels](https://github.com/vahid-anari/sciwidgets/blob/main/docs/panel.md) |
| `sciwidgets.plot` | `PlotCanvas`, `ScrollableFigure`, `CurveSelector`, `CurveCheckBox` | [Plot canvas](https://github.com/vahid-anari/sciwidgets/blob/main/docs/plot.md) |
| `sciwidgets.table` | `DataFrameModel`, `DataFrameView` (needs `pip install "sciwidgets[table]"`) | [DataFrame tables](https://github.com/vahid-anari/sciwidgets/blob/main/docs/table.md) |
| `sciwidgets.labels` | `MathLabel`, `set_latex_enabled` | [Labels](https://github.com/vahid-anari/sciwidgets/blob/main/docs/labels.md) |
| `sciwidgets.dialogs` | `show_information`, `show_warning`, `show_critical`, `show_rich_information`, `show_about_dialog`, `ask_question` | [Dialogs](https://github.com/vahid-anari/sciwidgets/blob/main/docs/dialogs.md) |
| `sciwidgets.splash` | `SplashScreen`, `splash_message` | [Splash screen](https://github.com/vahid-anari/sciwidgets/blob/main/docs/splash.md) |
| `sciwidgets.app` | `AppInfo`; `launcher.install_app_command`, `refresh_if_outdated`; `update.run_update`; `update_ui.AppUpdates` | [App launcher and updates](https://github.com/vahid-anari/sciwidgets/blob/main/docs/app.md) |
| `sciwidgets.window` | `MenuBarController`, `StatusBarController`, `center_on_screen` | [Window helpers](https://github.com/vahid-anari/sciwidgets/blob/main/docs/window.md) |
| `sciwidgets.style`, `sciwidgets.formatting` | `apply_sci_style`, `SciStyle`, `value_to_text`, `pretty_sci_text` | [Style and formatting](https://github.com/vahid-anari/sciwidgets/blob/main/docs/style.md) |

## Installation

```bash
pip install sciwidgets
```

Requires Python 3.10+, PySide6 6.5+, Matplotlib and NumPy (installed
automatically). A LaTeX installation is optional. The table widgets need
pandas: `pip install "sciwidgets[table]"`.

## Quick start

```python
import sys

from PySide6.QtWidgets import QApplication, QVBoxLayout, QWidget

from sciwidgets.params import FloatRangeSlider, FloatSlider
from sciwidgets.style import apply_sci_style

app = QApplication(sys.argv)
apply_sci_style(app)  # required, see "Style" below

win = QWidget()
layout = QVBoxLayout(win)

t1 = FloatSlider(
    label="T_1", unit=r"\mathrm{ms}",
    min_val=0.1, max_val=10.0, init_val=1.0, val_fmt="{:.2f}",
    min_limit=0.0, min_limit_inclusive=False,
)
band = FloatRangeSlider(
    label=r"\nu", unit=r"\mathrm{GHz}",
    min_val=6.60, max_val=6.75, init_vals=(6.65, 6.70), val_fmt="{:.3f}",
)
layout.addWidget(t1)
layout.addWidget(band)

t1.valueChanged.connect(lambda v: print("T1 =", v))
band.valueChanged.connect(lambda v: print("band =", v["range"]))

win.show()
sys.exit(app.exec())
```

Labels and units are written in LaTeX math mode, without the `$` signs.

## Style

The widgets rely on `SciStyle`, a Fusion-based Qt style, for part of their
behaviour: clicking a slider groove moves the handle there, disabled sliders
get a flat groove, and invalid numeric input gets a red frame. Apply it once
at startup:

```python
from sciwidgets.style import apply_sci_style

apply_sci_style(app, my_app_style_sheet)  # your own rules are appended
```

## Signals

`valueChanged`, `defaultChanged` and `configChanged` are emitted **only for
user actions** (dragging, typing, the context menu, dialogs). Setting values
from code with `set_value`, `set_config` and similar methods is silent, so
loading saved parameters never triggers your handlers. Read the new state
with `get_value()` / `get_config()` after setting it.

## Demos

Each subpackage has a runnable demo:

```bash
python -m sciwidgets.labels
python -m sciwidgets.dialogs
python -m sciwidgets.params
python -m sciwidgets.params.sliders
python -m sciwidgets.window
python -m sciwidgets.panel
python -m sciwidgets.plot
python -m sciwidgets.splash
```

## Versions

Versions follow [semantic versioning](https://semver.org); what changed in each
is in [`CHANGELOG.md`](CHANGELOG.md). Pin a compatible range in your app's
requirements (for example `sciwidgets~=0.10.4`) and move to a newer version
when you are ready to test it.

## Development

From the repo root:

```bash
pip install -e ".[dev]"
pytest
```

The tests run without a window (Qt's offscreen platform) and take a few
seconds. Pushing a tag `vX.Y.Z` publishes a GitHub Release with that
version's section of `CHANGELOG.md`.

## Citing

If you use sciwidgets in published work, please cite it; GitHub's **Cite this
repository** button gives the reference (from `CITATION.cff`).

## License

MIT License. See [LICENSE](LICENSE).

## Author

Vahid Anari ·
[GitHub](https://github.com/vahid-anari) ·
[LinkedIn](https://www.linkedin.com/in/vahid-anari/)

Related projects: [mbsolver](https://github.com/vahid-anari/mbsolver) ·
[Maxwell Bloch Studio](https://github.com/vahid-anari/maxwell-bloch-studio) ·
[linecat](https://github.com/vahid-anari/linecat)
