import asyncio
from inspect import iscoroutinefunction
try:
import wx.html2
except ImportError:
pass
try:
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWebChannel import QWebChannel
from PyQt5.QtCore import QObject, pyqtSlot
class Bridge(QObject):
def __init__(self, chart):
super().__init__()
self.chart = chart
@pyqtSlot(str)
def callback(self, message):
_widget_message(self.chart, message)
except ImportError:
pass
try:
from streamlit.components.v1 import html
except ImportError:
pass
try:
from IPython.display import HTML, display
except ImportError:
pass
from lightweight_charts.js import LWC, TopBar, CALLBACK_SCRIPT
def _widget_message(chart, string):
messages = string.split('__')
name, chart_id = messages[:2]
arg = messages[2]
chart.api.chart = chart._charts[chart_id]
method = getattr(chart.api, name)
if widget := chart.api.chart.topbar._widget_with_method(name):
widget.value = arg
asyncio.create_task(getattr(chart.api, name)()) if iscoroutinefunction(method) else method()
else:
asyncio.create_task(getattr(chart.api, name)(arg)) if iscoroutinefunction(method) else method(arg)
class WxChart(LWC):
def __init__(self, parent, volume_enabled: bool = True, inner_width: float = 1.0, inner_height: float = 1.0,
api: object = None, topbar: bool = False, searchbox: bool = False):
try:
self.webview: wx.html2.WebView = wx.html2.WebView.New(parent)
except NameError:
raise ModuleNotFoundError('wx.html2 was not found, and must be installed to use WxChart.')
super().__init__(volume_enabled, inner_width=inner_width, inner_height=inner_height)
self.api = api
self._script_func = self.webview.RunScript
self._js_api_code = 'window.wx_msg.postMessage.bind(window.wx_msg)'
self.webview.Bind(wx.html2.EVT_WEBVIEW_LOADED, lambda e: wx.CallLater(500, self._on_js_load))
self.webview.Bind(wx.html2.EVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, lambda e: _widget_message(self, e.GetString()))
self.webview.AddScriptMessageHandler('wx_msg')
self.webview.SetPage(self._html, '')
self.webview.AddUserScript(CALLBACK_SCRIPT)
self._create_chart()
self.topbar = TopBar(self) if topbar else None
self._make_search_box() if searchbox else None
def get_webview(self): return self.webview
class QtChart(LWC):
def __init__(self, widget=None, api: object = None, topbar: bool = False, searchbox: bool = False,
volume_enabled: bool = True, inner_width: float = 1.0, inner_height: float = 1.0):
try:
self.webview = QWebEngineView(widget)
except NameError:
raise ModuleNotFoundError('QWebEngineView was not found, and must be installed to use QtChart.')
super().__init__(volume_enabled, inner_width=inner_width, inner_height=inner_height)
self.api = api
self._script_func = self.webview.page().runJavaScript
self._js_api_code = 'window.pythonObject.callback'
self.web_channel = QWebChannel()
self.bridge = Bridge(self)
self.web_channel.registerObject('bridge', self.bridge)
self.webview.page().setWebChannel(self.web_channel)
self.webview.loadFinished.connect(self._on_js_load)
self._html = f'''
{self._html[:85]}
{self._html[85:]}
'''
self.webview.page().setHtml(self._html)
self.run_script(CALLBACK_SCRIPT)
self._create_chart()
self.topbar = TopBar(self) if topbar else None
self._make_search_box() if searchbox else None
def get_webview(self): return self.webview
class StaticLWC(LWC):
def __init__(self, volume_enabled=True, width=None, height=None, inner_width=1, inner_height=1):
super().__init__(volume_enabled, inner_width, inner_height)
self.width = width
self.height = height
self._html = self._html.replace('\n