Source code for QuteChartjs.core

import functools
import json
from typing import Any, Callable, Dict

from jinja2 import Template
from property_manager import writable_property

from QuteChartjs import log
from QuteChartjs.internals import QColor, QEventLoop, QWebEnginePage, __binding__


[docs]class QtEncoder(json.JSONEncoder):
[docs] def default(self, obj): if isinstance(obj, QColor): return obj.name() return json.JSONEncoder.default(self, obj)
[docs]class javascript_property(writable_property): def __set__(self, instance, value): if isinstance(instance, ChartNode): script = """{{obj}}.{{prop}} = {{value}}""" fn = functools.partial(super().__set__, instance) if __binding__ == "PySide2": fn(value) instance.root.execute( script, kwargs=dict( obj=instance.fullname(), prop=self.__name__, value=json.dumps(value, cls=QtEncoder), ), callback=fn, synchronous=__binding__ != "PySide2", )
[docs]class Node: def __init__(self, name: str, parent=None) -> None: self._name = name self._parent = parent @property def name(self) -> str: return self._name @property def parent(self) -> "Node": return self._parent @property def root(self) -> "Node": if self.parent is not None: return self.parent return self
[docs]class ChartNode(Node): def __init__(self, name: str = "", parent: "Node" = None) -> None: super().__init__(name, parent) self._page = None if isinstance(self.parent, ChartNode): self._page = self.parent.page @property def page(self) -> "QWebEnginePage": return self._page
[docs] def fullname(self) -> str: if self.parent is None: return self.name return f"{self.parent.fullname()}.{self.name}"
[docs]class RootNode(ChartNode): def __init__(self, name: str = "") -> None: super().__init__(name)
[docs] def execute( self, script: str, *, callback: Callable[[Any], None] = None, kwargs: Dict[str, Any] = None, synchronous: bool = False, ) -> None: kwargs = kwargs or {} kwargs["root"] = self.fullname() template = Template(script) js = template.render(**kwargs) log.js.debug(f"script: {js}") if self.page is not None: loop = QEventLoop() def internal_callback(args): if callable(callback): log.js.debug(f"res: {args}") callback(args) if synchronous: loop.quit() if __binding__ == "PySide2": self.page.runJavaScript(js) return self.page.runJavaScript(js, internal_callback) if synchronous: loop.exec_()