PySide6 WebEngine本地加载plotly-latest.min.js失败的问题求助
PySide6 WebEngine本地加载plotly-latest.min.js失败的问题求助
我来帮你搞定这个问题!你碰到的Uncaught ReferenceError: Plotly is not defined错误,主要是因为QWebEngineView加载本地文件的安全限制,还有路径处理的小细节没做好。下面给你调整好的完整代码,再一步步说清楚问题出在哪:
一、修正后的完整代码(本地加载JS文件版本)
import sys import plotly.graph_objects as go from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout from PySide6.QtWebEngineWidgets import QWebEngineView from PySide6.QtCore import QDir, QUrl import plotly.offline as po class GraphWidget(QWebEngineView): def __init__(self): super().__init__() # 创建示例散点图 fig = go.Figure(data=go.Scatter(x=[1,2,3,4,5], y=[5,4,3,2,1], mode='lines+markers')) # 确保plotly-latest.min.js在当前工作目录,或者替换成绝对路径 js_file_path = QDir.current().filePath('plotly-latest.min.js') # 转换为本地文件URL local_js_url = QUrl.fromLocalFile(js_file_path).toString() # 生成HTML内容 plot_div = po.plot(fig, include_plotlyjs=False, output_type='div') raw_html = f""" <html> <head> <meta charset="utf-8" /> <script src="{local_js_url}"></script> <style> body {{ margin: 0; background-color: rgb(44, 49, 60); }} .plot-container {{ width: 100%; height: 100%; }} </style> </head> <body> {plot_div} </body> </html> """ # 关键:设置HTML时指定baseUrl为JS文件所在目录,确保能正确加载本地资源 base_url = QUrl.fromLocalFile(QDir.current().path()) self.setHtml(raw_html, baseUrl=base_url) class MainWindow(QWidget): def __init__(self): super().__init__() self.setWindowTitle('Plotly Graph in GUI') self.setGeometry(100, 100, 800, 600) self.graph_widget = GraphWidget() layout = QVBoxLayout(self) layout.addWidget(self.graph_widget) self.show() if __name__ == '__main__': # 添加参数解除本地文件加载的安全限制 sys.argv.append("--disable-web-security") sys.argv.append("--allow-file-access-from-files") # 额外加这个更稳妥 app = QApplication(sys.argv) window = MainWindow() sys.exit(app.exec())
二、代码调整的关键要点
- 不要混用PyQt5和PySide6模块:你之前的代码里导入了PyQt5的
QDir、QUrl,这会导致API冲突,全部换成PySide6的对应模块就好。 - 设置
setHtml的baseUrl参数:这是你之前代码最核心的问题!setHtml默认的基准URL是about:blank,浏览器会把本地JS文件的URL当成相对这个空白页面的路径,自然加载失败。指定baseUrl为JS文件所在的目录,就能让浏览器正确解析本地资源路径。 - 补充安全参数:除了
--disable-web-security,再加--allow-file-access-from-files,进一步避免本地文件的访问限制。 - 确认JS文件路径正确:要保证
plotly-latest.min.js确实在你的Python脚本运行的当前工作目录里,或者直接写绝对路径(比如C:/your/path/plotly-latest.min.js)。
三、更稳妥的替代方案:直接嵌入JS内容
如果还是担心路径问题,你可以把plotly-latest.min.js的内容直接嵌入到HTML里,完全不用处理文件路径:
import sys import plotly.graph_objects as go from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout from PySide6.QtWebEngineWidgets import QWebEngineView import plotly.offline as po class GraphWidget(QWebEngineView): def __init__(self): super().__init__() fig = go.Figure(data=go.Scatter(x=[1,2,3,4,5], y=[5,4,3,2,1], mode='lines+markers')) plot_div = po.plot(fig, include_plotlyjs=False, output_type='div') # 读取本地JS文件的内容 with open('plotly-latest.min.js', 'r', encoding='utf-8') as f: plotly_js_content = f.read() raw_html = f""" <html> <head> <meta charset="utf-8" /> <script>{plotly_js_content}</script> <style> body {{ margin: 0; background-color: rgb(44, 49, 60); }} .plot-container {{ width: 100%; height: 100%; }} </style> </head> <body> {plot_div} </body> </html> """ self.setHtml(raw_html) class MainWindow(QWidget): def __init__(self): super().__init__() self.setWindowTitle('Plotly Graph in GUI') self.setGeometry(100, 100, 800, 600) self.graph_widget = GraphWidget() layout = QVBoxLayout(self) layout.addWidget(self.graph_widget) self.show() if __name__ == '__main__': app = QApplication(sys.argv) window = MainWindow() sys.exit(app.exec())
这个方案完全绕开了本地文件加载的路径和安全问题,打包发布的时候也更省心,不用担心JS文件路径出错。
备注:内容来源于stack exchange,提问作者Voice
相关产品推荐
相关产品推荐

