Skip to content

Commit

Permalink
Docs (#124)
Browse files Browse the repository at this point in the history
* wip

* wip

* more wip

* progress

* more docs

* more changes

* add link

* more examples and improvements

* fix check-manifest

* sort members

* remove autogen images

* remove _images

* add font docs

* add link to utils
  • Loading branch information
tlambert03 authored Oct 5, 2022
1 parent d1c0568 commit 97bb814
Show file tree
Hide file tree
Showing 45 changed files with 1,393 additions and 540 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,4 @@ src/superqt/_version.py
screenshots

.mypy_cache
docs/_auto_images/
21 changes: 14 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# ![tiny](https://user-images.githubusercontent.com/1609449/120636353-8c3f3800-c43b-11eb-8732-a14dec578897.png) superqt!


[![License](https://img.shields.io/pypi/l/superqt.svg?color=green)](https://github.com/napari/superqt/raw/master/LICENSE)
[![PyPI](https://img.shields.io/pypi/v/superqt.svg?color=green)](https://pypi.org/project/superqt)
[![Python
Expand All @@ -20,25 +19,33 @@ Components are tested on:
- PyQt5 (5.11 and above) & PyQt6
- PySide2 (5.11 and above) & PySide6

## Documentation

Documentation is available at https://napari.org/superqt

## Widgets

Widgets include:
superqt provides a variety of widgets that are not included in the native QtWidgets module, including multihandle (range) sliders, comboboxes, and more.

- [Float Slider](docs/sliders.md#float-slider)
See the [widgets documentation](https://napari.org/superqt/widgets) for a full list of widgets.

- [Range Slider](docs/sliders.md#range-slider) (multi-handle slider)

<img src="https://raw.githubusercontent.com/napari/superqt/main/docs/images/demo_darwin10.png" alt="range sliders" width=680>


- [Labeled Sliders](docs/sliders.md#labeled-sliders) (sliders with linked
spinboxes)

<img src="https://raw.githubusercontent.com/napari/superqt/main/docs/images/labeled_qslider.png" alt="range sliders" width=680>

<img src="https://raw.githubusercontent.com/napari/superqt/main/docs/images/labeled_range.png" alt="range sliders" width=680>

- Unbound Integer SpinBox (backed by python `int`)
## Utilities

superqt includes a number of utitlities for working with Qt, including:

- tools and decorators for working with threads in qt.
- `superqt.fonticon` for generating icons from font files (such as [Material Design Icons](https://materialdesignicons.com/) and [Font Awesome](https://fontawesome.com/))

See the [utilities documentation](https://napari.org/superqt/utilities/) for a full list of widgets.

## Contributing

Expand Down
144 changes: 144 additions & 0 deletions docs/_macros.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import sys
from enum import EnumMeta
from importlib import import_module
from pathlib import Path
from textwrap import dedent
from typing import TYPE_CHECKING

from jinja2 import pass_context
from qtpy.QtCore import QObject, Signal

if TYPE_CHECKING:
from mkdocs_macros.plugin import MacrosPlugin

EXAMPLES = Path(__file__).parent.parent / "examples"
IMAGES = Path(__file__).parent / "_auto_images"
IMAGES.mkdir(exist_ok=True, parents=True)


def define_env(env: "MacrosPlugin"):
@env.macro
@pass_context
def show_widget(context, width: int = 500) -> list[Path]:
# extract all fenced code blocks starting with "python"
page = context["page"]
dest = IMAGES / f"{page.title}.png"
if "build" in sys.argv:
dest.unlink(missing_ok=True)

codeblocks = [
b[6:].strip()
for b in page.markdown.split("```")
if b.startswith("python")
]
src = codeblocks[0].strip()
src = src.replace(
"QApplication([])", "QApplication.instance() or QApplication([])"
)
src = src.replace("app.exec_()", "")

exec(src)
_grab(dest, width)
return f"![{page.title}](../{dest.parent.name}/{dest.name}){{ loading=lazy; width={width} }}\n\n"

@env.macro
def show_members(cls: str):
# import class
module, name = cls.rsplit(".", 1)
_cls = getattr(import_module(module), name)

first_q = next(
(
b.__name__
for b in _cls.__mro__
if issubclass(b, QObject) and ".Qt" in b.__module__
),
None,
)

inherited_members = set()
for base in _cls.__mro__:
if issubclass(base, QObject) and ".Qt" in base.__module__:
inherited_members.update(
{k for k in dir(base) if not k.startswith("_")}
)

new_signals = {
k
for k, v in vars(_cls).items()
if not k.startswith("_") and isinstance(v, Signal)
}

self_members = {
k
for k in dir(_cls)
if not k.startswith("_") and k not in inherited_members | new_signals
}

enums = []
for m in list(self_members):
if isinstance(getattr(_cls, m), EnumMeta):
self_members.remove(m)
enums.append(m)

out = ""
if first_q:
url = f"https://doc.qt.io/qt-6/{first_q.lower()}.html"
out += f"## Qt Class\n\n<a href='{url}'>`{first_q}`</a>\n\n"

out += ""

if new_signals:
out += "## Signals\n\n"
for sig in new_signals:
out += f"### `{sig}`\n\n"

if enums:
out += "## Enums\n\n"
for e in enums:
out += f"### `{_cls.__name__}.{e}`\n\n"
for m in getattr(_cls, e):
out += f"- `{m.name}`\n\n"

if self_members:

out += dedent(
f"""
## Methods
::: {cls}
options:
heading_level: 3
show_source: False
show_inherited_members: false
show_signature_annotations: True
members: {sorted(self_members)}
docstring_style: numpy
show_bases: False
show_root_toc_entry: False
show_root_heading: False
"""
)

return out


def _grab(dest: str | Path, width) -> list[Path]:
"""Grab the top widgets of the application."""
from qtpy.QtCore import QTimer
from qtpy.QtWidgets import QApplication

w = QApplication.topLevelWidgets()[-1]
w.setFixedWidth(width)
w.activateWindow()
w.setMinimumHeight(40)
w.grab().save(str(dest))

# hack to make sure the object is truly closed and deleted
while True:
QTimer.singleShot(10, w.deleteLater)
QApplication.processEvents()
try:
w.parent()
except RuntimeError:
return
68 changes: 0 additions & 68 deletions docs/combobox.md

This file was deleted.

26 changes: 26 additions & 0 deletions docs/faq.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# FAQ

## Sliders not dragging properly on MacOS 12+

??? details
On MacOS Monterey, with Qt5, there is a bug that causes all sliders
(including native Qt sliders) to not respond properly to drag events. See:

- [https://bugreports.qt.io/browse/QTBUG-98093](https://bugreports.qt.io/browse/QTBUG-98093)
- [https://github.com/napari/superqt/issues/74](https://github.com/napari/superqt/issues/74)

Superqt includes a workaround for this issue, but it is not perfect, and it requires using a custom stylesheet (which may interfere with your own styles). Note that you
may not see this issue if you're already using custom stylesheets.

To opt in to the workaround, do any of the following:

- set the environment variable `USE_MAC_SLIDER_PATCH=1` before importing superqt
(note: this is safe to use even if you're targeting more than just MacOS 12, it will only be applied when needed)
- call the `applyMacStylePatch()` method on any of the superqt slider subclasses (note, this will override your slider styles)
- apply the stylesheet manually:

```python
from superqt.sliders import MONTEREY_SLIDER_STYLES_FIX

slider.setStyleSheet(MONTEREY_SLIDER_STYLES_FIX)
```
Empty file removed docs/fonticon.md
Empty file.
29 changes: 29 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# superqt

## ![tiny](https://user-images.githubusercontent.com/1609449/120636353-8c3f3800-c43b-11eb-8732-a14dec578897.png) "missing" widgets and components for PyQt/PySide

This repository aims to provide high-quality community-contributed Qt widgets
and components for [PyQt](https://riverbankcomputing.com/software/pyqt/) &
[PySide](https://www.qt.io/qt-for-python) that are not provided in the native
QtWidgets module.

Components are tested on:

- macOS, Windows, & Linux
- Python 3.7 and above
- PyQt5 (5.11 and above) & PyQt6
- PySide2 (5.11 and above) & PySide6

## Installation

```bash
pip install superqt
```

```bash
conda install -c conda-forge superqt
```

## Usage

See the [Widgets](./widgets/) and [Utilities](./utilities/) pages for features offered by superqt.
8 changes: 0 additions & 8 deletions docs/listwidgets.md

This file was deleted.

Loading

0 comments on commit 97bb814

Please sign in to comment.