mirror of
https://github.com/bec-project/bec_widgets.git
synced 2025-07-14 11:41:49 +02:00
refactor: add pydantic config, add change_theme
This commit is contained in:
@ -1,8 +1,30 @@
|
||||
import re
|
||||
|
||||
from pydantic import Field, field_validator
|
||||
from qtpy.QtWidgets import QTextEdit
|
||||
|
||||
from bec_widgets.utils import BECConnector
|
||||
from bec_widgets.utils.bec_connector import BECConnector, ConnectionConfig
|
||||
from bec_widgets.utils.colors import Colors
|
||||
|
||||
|
||||
class TextBoxConfig(ConnectionConfig):
|
||||
|
||||
theme: str = Field("dark", description="The theme of the figure widget.")
|
||||
font_color: str = Field("#FFF", description="The font color of the text")
|
||||
background_color: str = Field("#000", description="The background color of the widget.")
|
||||
font_size: int = Field(16, description="The font size of the text in the widget.")
|
||||
text: str = Field("", description="The text to display in the widget.")
|
||||
|
||||
@classmethod
|
||||
@field_validator("theme")
|
||||
def validate_theme(cls, v):
|
||||
"""Validate the theme of the figure widget."""
|
||||
if v not in ["dark", "light"]:
|
||||
raise ValueError("Theme must be either 'dark' or 'light'")
|
||||
return v
|
||||
|
||||
_validate_font_color = field_validator("font_color")(Colors.validate_color)
|
||||
_validate_background_color = field_validator("background_color")(Colors.validate_color)
|
||||
|
||||
|
||||
class TextBox(BECConnector, QTextEdit):
|
||||
@ -10,48 +32,76 @@ class TextBox(BECConnector, QTextEdit):
|
||||
USER_ACCESS = ["set_color", "set_text", "set_font_size"]
|
||||
|
||||
def __init__(self, text: str = "", parent=None, client=None, config=None, gui_id=None):
|
||||
if config is None:
|
||||
config = TextBoxConfig(widget_class=self.__class__.__name__)
|
||||
else:
|
||||
if isinstance(config, dict):
|
||||
config = TextBoxConfig(**config)
|
||||
self.config = config
|
||||
super().__init__(client=client, config=config, gui_id=gui_id)
|
||||
QTextEdit.__init__(self, parent=parent)
|
||||
|
||||
self.config = config
|
||||
self.setReadOnly(True)
|
||||
self._background_color = "#FFF"
|
||||
self._font_color = "#000"
|
||||
self._font_size = 12
|
||||
self.set_color(self._background_color, self._font_color)
|
||||
self.setGeometry(self.rect())
|
||||
self._text = text
|
||||
self.set_color(self.config.background_color, self.config.font_color)
|
||||
if not text:
|
||||
text = "<h1>Welcome to the BEC Widget TextBox</h1><p>A widget that allows user to display text in plain and HTML format.</p><p>This is an example of displaying HTML text.</p>"
|
||||
self.set_text(text)
|
||||
|
||||
def change_theme(self) -> None:
|
||||
"""
|
||||
Change the theme of the figure widget.
|
||||
"""
|
||||
if self.config.theme == "dark":
|
||||
theme = "light"
|
||||
font_color = "#000"
|
||||
background_color = "#FFF"
|
||||
else:
|
||||
theme = "dark"
|
||||
font_color = "#FFF"
|
||||
background_color = "#000"
|
||||
self.config.theme = theme
|
||||
self.set_color(background_color, font_color)
|
||||
|
||||
def set_color(self, background_color: str, font_color: str) -> None:
|
||||
"""Set the background color of the Widget.
|
||||
"""Set the background color of the widget.
|
||||
|
||||
Args:
|
||||
background_color (str): The color to set the background in HEX.
|
||||
font_color (str): The color to set the font in HEX.
|
||||
|
||||
"""
|
||||
self._background_color = background_color
|
||||
self._font_color = font_color
|
||||
self.config.background_color = background_color
|
||||
self.config.font_color = font_color
|
||||
self._update_stylesheet()
|
||||
|
||||
def set_font_size(self, size: int) -> None:
|
||||
"""Set the font size of the text in the Widget."""
|
||||
self._font_size = size
|
||||
"""Set the font size of the text in the widget.
|
||||
|
||||
Args:
|
||||
size (int): The font size to set.
|
||||
"""
|
||||
self.config.font_size = size
|
||||
self._update_stylesheet()
|
||||
|
||||
def _update_stylesheet(self):
|
||||
"""Update the stylesheet of the widget."""
|
||||
self.setStyleSheet(
|
||||
f"background-color: {self._background_color}; color: {self._font_color}; font-size: {self._font_size}px"
|
||||
f"background-color: {self.config.background_color}; color: {self.config.font_color}; font-size: {self.config.font_size}px"
|
||||
)
|
||||
|
||||
def set_text(self, text: str) -> None:
|
||||
"""Set the text of the Widget"""
|
||||
"""Set the text of the widget.
|
||||
|
||||
Args:
|
||||
text (str): The text to set.
|
||||
"""
|
||||
if self.is_html(text):
|
||||
self.setHtml(text)
|
||||
else:
|
||||
self.setPlainText(text)
|
||||
self._text = text
|
||||
self.config.text = text
|
||||
|
||||
def is_html(self, text: str) -> bool:
|
||||
"""Check if the text contains HTML tags.
|
||||
|
@ -18,26 +18,38 @@ def text_box_widget(qtbot, mocked_client):
|
||||
|
||||
|
||||
def test_textbox_widget(text_box_widget):
|
||||
|
||||
text_box_widget.set_text("Hello World!")
|
||||
# pylint: disable=protected-access
|
||||
assert text_box_widget._text == "Hello World!"
|
||||
"""Test the TextBox widget."""
|
||||
text = "Hello World!"
|
||||
text_box_widget.set_text(text)
|
||||
assert text_box_widget.toPlainText() == text
|
||||
|
||||
text_box_widget.set_color("#FFDDC1", "#123456")
|
||||
text_box_widget.set_font_size(20)
|
||||
assert (
|
||||
text_box_widget.styleSheet() == "background-color: #FFDDC1; color: #123456; font-size: 20px"
|
||||
)
|
||||
text_box_widget.set_color("white", "blue")
|
||||
text_box_widget.set_font_size(14)
|
||||
assert text_box_widget.styleSheet() == "background-color: white; color: blue; font-size: 14px"
|
||||
text = "<h1>Welcome to PyQt6</h1><p>This is an example of displaying <strong>HTML</strong> text.</p>"
|
||||
with mock.patch.object(text_box_widget, "setHtml") as mocked_set_html:
|
||||
text_box_widget.set_text(text)
|
||||
assert mocked_set_html.call_count == 1
|
||||
assert mocked_set_html.call_args == mock.call(text)
|
||||
|
||||
with mock.patch.object(text_box_widget, "setHtml") as mock_set_plain_text:
|
||||
text_box_widget.set_text(
|
||||
"<h1>Welcome to PyQt6</h1><p>This is an example of displaying <strong>HTML</strong> text.</p>"
|
||||
)
|
||||
assert mock_set_plain_text.call_args == mock.call(
|
||||
"<h1>Welcome to PyQt6</h1><p>This is an example of displaying <strong>HTML</strong> text.</p>"
|
||||
)
|
||||
# pylint: disable=protected-access
|
||||
|
||||
def test_textbox_change_theme(text_box_widget):
|
||||
"""Test change theme functionaility"""
|
||||
# Default is dark theme
|
||||
text_box_widget.change_theme()
|
||||
assert text_box_widget.config.theme == "light"
|
||||
assert (
|
||||
text_box_widget._text
|
||||
== "<h1>Welcome to PyQt6</h1><p>This is an example of displaying <strong>HTML</strong> text.</p>"
|
||||
text_box_widget.styleSheet()
|
||||
== f"background-color: #FFF; color: #000; font-size: {text_box_widget.config.font_size}px"
|
||||
)
|
||||
text_box_widget.change_theme()
|
||||
assert text_box_widget.config.theme == "dark"
|
||||
assert (
|
||||
text_box_widget.styleSheet()
|
||||
== f"background-color: #000; color: #FFF; font-size: {text_box_widget.config.font_size}px"
|
||||
)
|
||||
|
Reference in New Issue
Block a user