add support for pyqt6, throw error and suggest downgrade for wx, streamlit, jupyter

This commit is contained in:
louisnw
2024-05-25 13:36:54 +01:00
parent 906571e4fb
commit a52cd8f4a7

View File

@ -10,18 +10,25 @@ except ImportError:
wx = None wx = None
try: try:
using_py6 = False using_pyside6 = False
from PyQt5.QtWebEngineWidgets import QWebEngineView from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWebChannel import QWebChannel from PyQt5.QtWebChannel import QWebChannel
from PyQt5.QtCore import QObject, pyqtSlot as Slot from PyQt5.QtCore import QObject, pyqtSlot as Slot, QUrl, QTimer
except ImportError: except ImportError:
using_py6 = True using_pyside6 = True
try: try:
from PySide6.QtWebEngineWidgets import QWebEngineView from PySide6.QtWebEngineWidgets import QWebEngineView
from PySide6.QtWebChannel import QWebChannel from PySide6.QtWebChannel import QWebChannel
from PySide6.QtCore import Qt, QObject, Slot from PySide6.QtCore import Qt, QObject, Slot, QUrl, QTimer
except ImportError: except ImportError:
QWebEngineView = None try:
using_pyside6 = False
from PyQt6.QtWebEngineWidgets import QWebEngineView
from PyQt6.QtWebChannel import QWebChannel
from PyQt6.QtCore import QObject, pyqtSlot as Slot, QUrl, QTimer
except ImportError:
QWebEngineView = None
if QWebEngineView: if QWebEngineView:
class Bridge(QObject): class Bridge(QObject):
@ -54,16 +61,31 @@ def emit_callback(window, string):
class WxChart(abstract.AbstractChart): class WxChart(abstract.AbstractChart):
def __init__(self, parent, inner_width: float = 1.0, inner_height: float = 1.0, def __init__(self, parent, inner_width: float = 1.0, inner_height: float = 1.0,
scale_candles_only: bool = False, toolbox: bool = False): scale_candles_only: bool = False, toolbox: bool = False):
# this isn't available at the moment
raise ModuleNotFoundError('WxChart is not available in lightweight charts 2.0; please downgrade to an earlier version.')
if wx is None: if wx is None:
raise ModuleNotFoundError('wx.html2 was not found, and must be installed to use WxChart.') raise ModuleNotFoundError('wx.html2 was not found, and must be installed to use WxChart.')
self.webview: wx.html2.WebView = wx.html2.WebView.New(parent) self.webview: wx.html2.WebView = wx.html2.WebView.New(parent)
super().__init__(abstract.Window(self.webview.RunScript, 'window.wx_msg.postMessage.bind(window.wx_msg)'), super().__init__(abstract.Window(self.webview.RunScript, 'window.wx_msg.postMessage.bind(window.wx_msg)'),
inner_width, inner_height, scale_candles_only, toolbox) inner_width, inner_height, scale_candles_only, toolbox)
self.webview.Bind(wx.html2.EVT_WEBVIEW_LOADED, lambda e: wx.CallLater(500, self.win.on_js_load)) self.webview.Bind(wx.html2.EVT_WEBVIEW_LOADED, lambda e: wx.CallLater(1000, self.win.on_js_load))
self.webview.Bind(wx.html2.EVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, lambda e: emit_callback(self, e.GetString())) self.webview.Bind(wx.html2.EVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, lambda e: emit_callback(self, e.GetString()))
self.webview.AddScriptMessageHandler('wx_msg') self.webview.AddScriptMessageHandler('wx_msg')
self.webview.LoadURL(f'file:///{abstract.INDEX}') self.webview.LoadURL(f'file:///{abstract.INDEX}')
# with open(abstract.INDEX, 'r') as f:
# html = f.read()
# self.webview.SetPage(html, '/Users/louis/Projects/lightweight-charts-python/lightweight_charts/js/')
# with open('/Users/louis/Projects/lightweight-charts-python/lightweight_charts/js/bundle.js', 'r') as f:
# self.webview.AddUserScript(f.read())
# self.webview.AddUserScript(abstract.JS['toolbox']) if toolbox else None # self.webview.AddUserScript(abstract.JS['toolbox']) if toolbox else None
def get_webview(self): return self.webview def get_webview(self): return self.webview
@ -82,21 +104,25 @@ class QtChart(abstract.AbstractChart):
self.bridge = Bridge(self) self.bridge = Bridge(self)
self.web_channel.registerObject('bridge', self.bridge) self.web_channel.registerObject('bridge', self.bridge)
self.webview.page().setWebChannel(self.web_channel) self.webview.page().setWebChannel(self.web_channel)
self.webview.loadFinished.connect(self.win.on_js_load) self.webview.loadFinished.connect(lambda: self.webview.page().runJavaScript('''
if using_py6: let scriptElement = document.createElement("script")
scriptElement.src = 'qrc:///qtwebchannel/qwebchannel.js'
scriptElement.onload = function() {
var bridge = new QWebChannel(qt.webChannelTransport, function(channel) {
var pythonObject = channel.objects.bridge
window.pythonObject = pythonObject
})
}
document.head.appendChild(scriptElement)
'''))
self.webview.loadFinished.connect(lambda: QTimer.singleShot(200, self.win.on_js_load))
if using_pyside6:
self.webview.setContextMenuPolicy(Qt.ContextMenuPolicy.NoContextMenu) self.webview.setContextMenuPolicy(Qt.ContextMenuPolicy.NoContextMenu)
self._html = f''' self.webview.load(QUrl.fromLocalFile(abstract.INDEX))
{abstract.TEMPLATE[:85]}
<script src="qrc:///qtwebchannel/qwebchannel.js"></script>
<script>
var bridge = new QWebChannel(qt.webChannelTransport, function(channel) {{
var pythonObject = channel.objects.bridge;
window.pythonObject = pythonObject
}});
</script>
{abstract.TEMPLATE[85:]}
'''
self.webview.page().setHtml(self._html)
def get_webview(self): return self.webview def get_webview(self): return self.webview
@ -104,7 +130,27 @@ class QtChart(abstract.AbstractChart):
class StaticLWC(abstract.AbstractChart): class StaticLWC(abstract.AbstractChart):
def __init__(self, width=None, height=None, inner_width=1, inner_height=1, def __init__(self, width=None, height=None, inner_width=1, inner_height=1,
scale_candles_only: bool = False, toolbox=False, autosize=True): scale_candles_only: bool = False, toolbox=False, autosize=True):
self._html = abstract.TEMPLATE.replace('</script>\n</body>\n</html>', '')
# this isn't available at the moment
raise ModuleNotFoundError('Streamlit & Jupyter Charts are unavailable in lightweight charts 2.0; please downgrade to an earlier version.')
with open(abstract.INDEX.replace("test.html", 'styles.css'), 'r') as f:
css = f.read()
with open(abstract.INDEX.replace("test.html", 'bundle.js'), 'r') as f:
js = f.read()
with open(abstract.INDEX.replace("test.html", 'lightweight-charts.js'), 'r') as f:
lwc = f.read()
with open(abstract.INDEX, 'r') as f:
self._html = f.read().replace('</body>\n</html>', f'<script type="module">{lwc}</script><script type="module">{js}')
self._html = self._html.replace("</style>", f"{css}</style>")
self._html = self._html.replace('<script type="module" src="./bundle.js"></script>',
f'')
super().__init__(abstract.Window(run_script=self.run_script), inner_width, inner_height, super().__init__(abstract.Window(run_script=self.run_script), inner_width, inner_height,
scale_candles_only, toolbox, autosize) scale_candles_only, toolbox, autosize)
self.width = width self.width = width