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_()