This commit is contained in:
Talley Lambert
2022-10-04 16:21:48 -04:00
parent f7eb917db4
commit 190e6e2e8a
30 changed files with 279 additions and 51 deletions

View File

@@ -1,3 +1,4 @@
import sys
from enum import EnumMeta
from importlib import import_module
from pathlib import Path
@@ -6,7 +7,6 @@ from typing import TYPE_CHECKING
from jinja2 import pass_context
from qtpy.QtCore import QObject, Signal
from qtpy.QtWidgets import QApplication
if TYPE_CHECKING:
from mkdocs_macros.plugin import MacrosPlugin
@@ -14,38 +14,60 @@ if TYPE_CHECKING:
EXAMPLES = Path(__file__).parent.parent / "examples"
IMAGES = Path(__file__).parent / "images"
IMAGES.mkdir(exist_ok=True, parents=True)
# for p in IMAGES.glob("*.png"):
# p.unlink()
def define_env(env: "MacrosPlugin"):
@env.macro
@pass_context
def insert_example(context, example: str, width: int = 500) -> list[Path]:
"""Grab the top widgets of the application."""
if example.strip().startswith("```"):
src = dedent(example.strip())
src = "\n".join(src.split("\n")[1:-1])
key = context["page"].title
else:
if not example.endswith(".py"):
example += ".py"
src = (EXAMPLES / example).read_text()
key = example.replace(".py", "")
output = f"```python\n{src}\n```\n\n"
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)
dest = IMAGES / f"{key}.png"
if not (dest).exists():
code = [
b[6:].strip()
for b in page.markdown.split("```")
if b.startswith("python")
]
src = "\n".join(code).strip()
src = src.replace(
"QApplication([])", "QApplication.instance() or QApplication([])"
)
src = src.replace("app.exec_()", "")
_clear_widgets()
exec(src)
_grab(dest, width)
return f"![{page.title}](../images/{dest.name}){{ loading=lazy; width={width} }}\n\n"
output += f"![Image title](../images/{dest.name}){{ loading=lazy; width={width} }}\n\n"
return output
# @env.macro
# @pass_context
# def insert_example(context, example: str, width: int = 500) -> list[Path]:
# """Grab the top widgets of the application."""
# if example.strip().startswith("```"):
# src = dedent(example.strip())
# src = "\n".join(src.split("\n")[1:-1])
# key = context["page"].title
# else:
# if not example.endswith(".py"):
# example += ".py"
# src = (EXAMPLES / example).read_text()
# key = example.replace(".py", "")
# output = f"```python\n{src}\n```\n\n"
# dest = IMAGES / f"{key}.png"
# if not (dest).exists():
# src = src.replace(
# "QApplication([])", "QApplication.instance() or QApplication([])"
# )
# src = src.replace("app.exec_()", "")
# _clear_widgets()
# exec(src)
# _grab(dest, width)
# output += f"![Image title](../images/{dest.name}){{ loading=lazy; width={width} }}\n\n"
# return output
@env.macro
def show_members(cls: str):
@@ -92,9 +114,9 @@ def define_env(env: "MacrosPlugin"):
out += ""
if new_signals:
out += "## New Signals\n\n"
out += "## Signals\n\n"
for sig in new_signals:
out += f"### `{_cls.__name__}.{sig}`\n\n"
out += f"### `{sig}`\n\n"
if enums:
out += "## Enums\n\n"
@@ -117,6 +139,7 @@ def define_env(env: "MacrosPlugin"):
members: {self_members}
docstring_style: numpy
show_bases: False
show_root_toc_entry: False
"""
)
@@ -125,15 +148,20 @@ def define_env(env: "MacrosPlugin"):
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.setMinimumHeight(50)
w.activateWindow()
w.setMinimumHeight(40)
w.grab().save(str(dest))
def _clear_widgets() -> None:
for i in QApplication.topLevelWidgets():
i.close()
i.deleteLater()
# 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 980 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1012 B

View File

@@ -1 +1 @@
# superqt documentation
# superqt

View File

@@ -6,23 +6,23 @@ The following are QWidget subclasses:
| Widget | Description |
| ----------- | --------------------- |
| [`QDoubleSlider`](./qdoubleslider.md) | Slider for float values |
| [`QLabeledSlider`](./qlabeledslider.md) | `QSlider` with editable `QSpinBox` that shows the current value |
| [`QLabeledDoubleSlider`](./qlabeleddoubleslider.md) | `QSlider` for float values with editable `QSpinBox` with the current value |
| [`QRangeSlider`](./qrangeslider.md) | Multi-handle slider |
| [`QDoubleRangeSlider`](./qdoublerangeslider.md) | Multi-handle slider for float values |
| [`QLabeledRangeSlider`](./qlabeledrangeslider.md) | `QRangeSlider` variant, with editable labels for each handle |
| [`QDoubleRangeSlider`](./qdoublerangeslider.md) | Multi-handle slider for float values |
| [`QDoubleSlider`](./qdoubleslider.md) | Slider for float values |
| [`QLabeledDoubleRangeSlider`](./qlabeleddoublerangeslider.md) | `QDoubleRangeSlider` variant with editable labels for each handle |
| [`QLargeIntSpinBox`](./qlargeintspinbox.md) | `QSpinbox` that accepts arbitrarily large integers |
| [`QLabeledDoubleSlider`](./qlabeleddoubleslider.md) | `QSlider` for float values with editable `QSpinBox` with the current value |
| [`QLabeledRangeSlider`](./qlabeledrangeslider.md) | `QRangeSlider` variant, with editable labels for each handle |
| [`QLabeledSlider`](./qlabeledslider.md) | `QSlider` with editable `QSpinBox` that shows the current value |
| [`QLargeIntSpinBox`](./qlargeintspinbox.md) | `QSpinbox` that accepts arbitrarily large integers |
| [`QRangeSlider`](./qrangeslider.md) | Multi-handle slider |
## Labels and categorical inputs
| Widget | Description |
| ----------- | --------------------- |
| [`QSearchableListWidget`]() | `QListWidget` variant with search field that filters available options |
| [`QEnumComboBox`]() | `QComboBox` that populates the combobox from a python `Enum` |
| [`QSearchableComboBox`]() | `QComboBox` variant that filters available options based on text input |
| [`QElidingLabel`]() | A `QLabel` variant that will elide text (add `…`) to fit width. |
| [`QElidingLabel`](./qelidinglabel.md) | A `QLabel` variant that will elide text (add `…`) to fit width. |
| [`QEnumComboBox`](./qenumcombobox.md) | `QComboBox` that populates the combobox from a python `Enum` |
| [`QSearchableComboBox`](./qsearchablecombobox.md) | `QComboBox` variant that filters available options based on text input |
| [`QSearchableListWidget`](./qsearchablelistwidget.md) | `QListWidget` variant with search field that filters available options |
## Frames and containers

View File

@@ -1,5 +1,22 @@
# QCollapsible
{{ insert_example('qcollapsible', 350) }}
```python
from qtpy.QtWidgets import QApplication, QLabel, QPushButton
from superqt import QCollapsible
app = QApplication([])
collapsible = QCollapsible("Advanced analysis")
collapsible.addWidget(QLabel("This is the inside of the collapsible frame"))
for i in range(10):
collapsible.addWidget(QPushButton(f"Content button {i + 1}"))
collapsible.expand(animate=False)
collapsible.show()
app.exec_()
```
{{ show_widget(350) }}
{{ show_members('superqt.QCollapsible') }}

View File

@@ -0,0 +1,21 @@
# QDoubleRangeSlider
```python
from qtpy.QtCore import Qt
from qtpy.QtWidgets import QApplication
from superqt import QDoubleRangeSlider
app = QApplication([])
slider = QDoubleRangeSlider(Qt.Orientation.Horizontal)
slider.setRange(0, 1)
slider.setValue((0.2, 0.8))
slider.show()
app.exec_()
```
{{ show_widget() }}
{{ show_members('superqt.QDoubleRangeSlider') }}

View File

@@ -1,5 +1,21 @@
# QDoubleSlider
{{ insert_example('double_slider') }}
```python
from qtpy.QtCore import Qt
from qtpy.QtWidgets import QApplication
from superqt import QDoubleSlider
app = QApplication([])
slider = QDoubleSlider(Qt.Orientation.Horizontal)
slider.setRange(0, 1)
slider.setValue(0.5)
slider.show()
app.exec_()
```
{{ show_widget() }}
{{ show_members('superqt.QDoubleSlider') }}

View File

@@ -0,0 +1,23 @@
# QElidingLabel
```python
from qtpy.QtWidgets import QApplication
from superqt import QElidingLabel
app = QApplication([])
widget = QElidingLabel(
"a skj skjfskfj sdlf sdfl sdlfk jsdf sdlkf jdsf dslfksdl sdlfk sdf sdl "
"fjsdlf kjsdlfk laskdfsal as lsdfjdsl kfjdslf asfd dslkjfldskf sdlkfj"
)
widget.setWordWrap(True)
widget.resize(300, 20)
widget.show()
app.exec_()
```
{{ show_widget(300) }}
{{ show_members('superqt.QElidingLabel') }}

View File

@@ -0,0 +1,26 @@
# QEnumComboBox
```python
from enum import Enum
from qtpy.QtWidgets import QApplication
from superqt import QEnumComboBox
class SampleEnum(Enum):
first = 1
second = 2
third = 3
app = QApplication([])
combo = QEnumComboBox()
combo.setEnumClass(SampleEnum)
combo.show()
app.exec_()
```
{{ show_widget() }}
{{ show_members('superqt.QEnumComboBox') }}

View File

@@ -0,0 +1,21 @@
# QLabeledDoubleRangeSlider
```python
from qtpy.QtCore import Qt
from qtpy.QtWidgets import QApplication
from superqt import QLabeledDoubleRangeSlider
app = QApplication([])
slider = QLabeledDoubleRangeSlider(Qt.Orientation.Horizontal)
slider.setRange(0, 1)
slider.setValue((0.2, 0.8))
slider.show()
app.exec_()
```
{{ show_widget() }}
{{ show_members('superqt.QLabeledDoubleRangeSlider') }}

View File

@@ -1,7 +1,5 @@
# QLabeledDoubleSlider
{{ insert_example('
```python
from qtpy.QtCore import Qt
from qtpy.QtWidgets import QApplication
@@ -18,6 +16,6 @@ slider.show()
app.exec_()
```
') }}
{{ show_widget() }}
{{ show_members('superqt.QLabeledDoubleSlider') }}

View File

@@ -0,0 +1,20 @@
# QLabeledRangeSlider
```python
from qtpy.QtCore import Qt
from qtpy.QtWidgets import QApplication
from superqt import QLabeledRangeSlider
app = QApplication([])
slider = QLabeledRangeSlider(Qt.Orientation.Horizontal)
slider.setValue((20, 80))
slider.show()
app.exec_()
```
{{ show_widget() }}
{{ show_members('superqt.QLabeledRangeSlider') }}

View File

@@ -1,7 +1,5 @@
# QLabeledSlider
{{ insert_example('
```python
from qtpy.QtCore import Qt
from qtpy.QtWidgets import QApplication
@@ -17,6 +15,6 @@ slider.show()
app.exec_()
```
') }}
{{ show_widget() }}
{{ show_members('superqt.QLabeledSlider') }}

View File

@@ -0,0 +1,21 @@
# QLargeIntSpinBox
```python
from qtpy.QtCore import Qt
from qtpy.QtWidgets import QApplication
from superqt import QLargeIntSpinBox
app = QApplication([])
slider = QLargeIntSpinBox()
slider.setRange(0, 4.53e8)
slider.setValue(4.53e8)
slider.show()
app.exec_()
```
{{ show_widget(150) }}
{{ show_members('superqt.QLargeIntSpinBox') }}

View File

@@ -1,7 +1,5 @@
# QRangeSlider
{{ insert_example('
```python
from qtpy.QtCore import Qt
from qtpy.QtWidgets import QApplication
@@ -17,6 +15,6 @@ slider.show()
app.exec_()
```
') }}
{{ show_widget() }}
{{ show_members('superqt.QRangeSlider') }}

View File

@@ -0,0 +1,19 @@
# QSearchableComboBox
```python
from qtpy.QtWidgets import QApplication
from superqt import QSearchableComboBox
app = QApplication([])
combo = QSearchableComboBox()
combo.addItems(["foo", "bar", "baz", "foobar", "foobaz", "barbaz"])
combo.show()
app.exec_()
```
{{ show_widget() }}
{{ show_members('superqt.QSearchableComboBox') }}

View File

@@ -0,0 +1,19 @@
# QSearchableListWidget
```python
from qtpy.QtWidgets import QApplication
from superqt import QSearchableListWidget
app = QApplication([])
slider = QSearchableListWidget()
slider.addItems(["foo", "bar", "baz", "foobar", "foobaz", "barbaz"])
slider.show()
app.exec_()
```
{{ show_widget() }}
{{ show_members('superqt.QSearchableListWidget') }}

View File

@@ -19,6 +19,9 @@ theme:
name: material
features:
- navigation.instant
- navigation.indexes
# - navigation.tracking
# - navigation.tabs
- search.highlight
- search.suggest