You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 17:53:14