Move widget-style "format label" to our label mod

Might as well group similar components..
Drop form widget user input update logic, instead expect caller to
provide an async handler.
fsp_feeds
Tyler Goodlet 2021-08-25 10:32:17 -04:00
parent 16c1f727c7
commit c4add92422
2 changed files with 72 additions and 74 deletions

View File

@ -22,10 +22,12 @@ from __future__ import annotations
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
from functools import partial from functools import partial
from textwrap import dedent from textwrap import dedent
from typing import Optional, Any from typing import (
Optional, Any, Callable, Awaitable
)
import trio import trio
from PyQt5 import QtCore, QtGui from PyQt5 import QtGui
from PyQt5.QtCore import QSize, QModelIndex, Qt, QEvent from PyQt5.QtCore import QSize, QModelIndex, Qt, QEvent
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QWidget, QWidget,
@ -40,10 +42,11 @@ from PyQt5.QtWidgets import (
QStyledItemDelegate, QStyledItemDelegate,
QStyleOptionViewItem, QStyleOptionViewItem,
) )
import pydantic # import pydantic
from ._event import open_handlers from ._event import open_handlers
from ._style import hcolor, _font, _font_small, DpiAwareFont from ._style import hcolor, _font, _font_small, DpiAwareFont
from ._label import FormatLabel
from .. import brokers from .. import brokers
@ -327,7 +330,7 @@ async def handle_field_input(
widget: QWidget, widget: QWidget,
recv_chan: trio.abc.ReceiveChannel, recv_chan: trio.abc.ReceiveChannel,
form: FieldsForm, form: FieldsForm,
model: pydantic.BaseModel, # noqa on_value_change: Callable[[str, Any], Awaitable[bool]],
focus_next: QWidget, focus_next: QWidget,
) -> None: ) -> None:
@ -358,19 +361,9 @@ async def handle_field_input(
# process field input # process field input
if key in (Qt.Key_Enter, Qt.Key_Return): if key in (Qt.Key_Enter, Qt.Key_Return):
value = widget.text()
key = widget._key key = widget._key
value = widget.text()
old = getattr(model, key) await on_value_change(key, value)
try:
setattr(model, key, value)
except pydantic.error_wrappers.ValidationError:
setattr(model, key, old)
widget.setText(str(old))
print(model.dict())
def mk_form( def mk_form(
@ -416,6 +409,7 @@ async def open_form_input_handling(
form: FieldsForm, form: FieldsForm,
focus_next: QWidget, focus_next: QWidget,
on_value_change: Callable[[str, Any], Awaitable[bool]],
) -> FieldsForm: ) -> FieldsForm:
@ -431,8 +425,8 @@ async def open_form_input_handling(
async_handler=partial( async_handler=partial(
handle_field_input, handle_field_input,
form=form, form=form,
model=form.model,
focus_next=focus_next, focus_next=focus_next,
on_value_change=on_value_change,
), ),
# block key repeats? # block key repeats?
@ -520,56 +514,6 @@ class FillStatusBar(QProgressBar):
self.setValue(value) self.setValue(value)
class FormatLabel(QLabel):
def __init__(
self,
fmt_str: str,
font: QtGui.QFont,
font_size: int,
font_color: str,
parent=None,
) -> None:
super().__init__(parent)
# by default set the format string verbatim and expect user to
# call ``.format()`` later (presumably they'll notice the
# unformatted content if ``fmt_str`` isn't meant to be
# unformatted).
self.fmt_str = fmt_str
self.setText(fmt_str)
self.setStyleSheet(
f"""QLabel {{
color : {hcolor(font_color)};
font-size : {font_size}px;
}}
"""
)
self.setFont(_font.font)
self.setTextFormat(Qt.MarkdownText) # markdown
self.setMargin(0)
self.setAlignment(
QtCore.Qt.AlignVCenter
| QtCore.Qt.AlignLeft
)
self.setText(self.fmt_str)
def format(
self,
fields: dict[str, Any],
) -> str:
out = self.fmt_str.format(**fields)
self.setText(out)
return out
def mk_fill_status_bar( def mk_fill_status_bar(
fields: FieldsForm, fields: FieldsForm,
@ -694,11 +638,11 @@ def mk_order_pane_layout(
# '% of port', # '% of port',
], ],
}, },
'disti_weight': { # 'disti_weight': {
'label': '**weight**:', # 'label': '**weighting**:',
'type': 'select', # 'type': 'select',
'default_value': ['uniform'], # 'default_value': ['uniform'],
}, # },
'limit': { 'limit': {
'label': '**limit**:', 'label': '**limit**:',
'type': 'edit', 'type': 'edit',

View File

@ -19,15 +19,17 @@ Non-shitty labels that don't re-invent the wheel.
""" """
from inspect import isfunction from inspect import isfunction
from typing import Callable, Optional from typing import Callable, Optional, Any
import pyqtgraph as pg import pyqtgraph as pg
from PyQt5 import QtGui, QtWidgets from PyQt5 import QtGui, QtWidgets
from PyQt5.QtCore import QPointF, QRectF from PyQt5.QtWidgets import QLabel
from PyQt5.QtCore import QPointF, QRectF, Qt
from ._style import ( from ._style import (
DpiAwareFont, DpiAwareFont,
hcolor, hcolor,
_font,
) )
@ -226,3 +228,55 @@ class Label:
def delete(self) -> None: def delete(self) -> None:
self.vb.scene().removeItem(self.txt) self.vb.scene().removeItem(self.txt)
class FormatLabel(QLabel):
'''Kinda similar to above but using the widget apis.
'''
def __init__(
self,
fmt_str: str,
font: QtGui.QFont,
font_size: int,
font_color: str,
parent=None,
) -> None:
super().__init__(parent)
# by default set the format string verbatim and expect user to
# call ``.format()`` later (presumably they'll notice the
# unformatted content if ``fmt_str`` isn't meant to be
# unformatted).
self.fmt_str = fmt_str
self.setText(fmt_str)
self.setStyleSheet(
f"""QLabel {{
color : {hcolor(font_color)};
font-size : {font_size}px;
}}
"""
)
self.setFont(_font.font)
self.setTextFormat(Qt.MarkdownText) # markdown
self.setMargin(0)
self.setAlignment(
Qt.AlignVCenter
| Qt.AlignLeft
)
self.setText(self.fmt_str)
def format(
self,
fields: dict[str, Any],
) -> str:
out = self.fmt_str.format(**fields)
self.setText(out)
return out