问题
I am trying to embed a plotly graph into a PyQt5 webengine view. I was able to do so using the following:
open plotly in qwebview in interactive mode
If you read it, the article explains that you can't directly include the javascript in the HTML when using the webengine view (it has issues loading files above 2 MB). However, I'm trying to make it so that the source for the javascript is a local copy of plotly-min.js (saved in the project folder) so that anyone using the program doesn't need an internet connection to view the graphs it generates. I've tried to follow a few examples on html, but to no avail.
The original code that does work with an internet connection is:
raw_html = '<html><head><meta charset="utf-8" />'
raw_html += '<script src="https://cdn.plot.ly/plotly-latest.min.js"></script></head>'
raw_html += '<body>'
raw_html += plot(fig, include_plotlyjs=False, output_type='div')
raw_html += '</body></html>'
temp_view = QWebEngineView()
temp_view.setHtml(graph)
If I understand it correctly, I need to change this part:
<script src="https://cdn.plot.ly/plotly-latest.min.js">
I've already tried:
<script type="text/javascript" src="file:///C:/Users/UserName/PycharmProjects/ProjectFolder/plotly-latest.min.js"></script>
I honestly do not know HTML. This is the only HTML in the code (the rest is in Python 3). Does anyone know why the above might not work and what I need to change? I have a suspicion I might somehow be running into the 2 MB limit the above question referenced, as different variations I've found online for how to reference a local file in HTML don't seem to change anything.
回答1:
Many browsers for security reason disable the loading of local files, but as noted in the following forum you can enable that capability with:
sys.argv.append("--disable-web-security")
Assuming the .js is next to your .py file:
.
├── main.py
└── plotly-latest.min.js
you can use the following example:
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtCore import QDir, QUrl
import plotly
import plotly.graph_objs as go
sys.argv.append("--disable-web-security")
app = QApplication(sys.argv)
x1 = [10, 3, 4, 5, 20, 4, 3]
trace1 = go.Box(x = x1)
layout = go.Layout(showlegend = True)
data = [trace1]
fig = go.Figure(data=data, layout = layout)
path = QDir.current().filePath('plotly-latest.min.js')
local = QUrl.fromLocalFile(path).toString()
raw_html = '<html><head><meta charset="utf-8" />'
raw_html += '<script src="{}"></script></head>'.format(local)
raw_html += '<body>'
raw_html += plotly.offline.plot(fig, include_plotlyjs=False, output_type='div')
raw_html += '</body></html>'
view = QWebEngineView()
view.setHtml(raw_html)
view.show()
sys.exit(app.exec_())
回答2:
I had problems running the example of @eyllanesc under Ubuntu 16.04 / 18.04 with NVIDIA driver.
First I had to downgrade PyQt5
5.10.1
to 5.10.0
to avoid:
[0525/114545.216138:WARNING:stack_trace_posix.cc(648)] Failed to open file: /home/tmp/.gl5Qb0Tf (deleted)
Error: Datei oder Verzeichnis nicht gefunden
Could not find QtWebEngineProcess
[3032:3032:0525/114545.495351:FATAL:zygote_host_impl_linux.cc(182)] Check failed: ReceiveFixedMessage(fds[0], kZygoteBootMessage, sizeof(kZygoteBootMessage), &boot_pid).
...
But this should be fixed for the future in PyQt5 5.11
The second problem was the linking of the shader (ubuntu 16.04
):
QOpenGLShaderProgram::uniformLocation(qt_Matrix): shader program is not linked
QOpenGLShaderProgram: could not create shader program
QOpenGLShader: could not create shader
QOpenGLShader: could not create shader
shader compilation failed:
Under ubuntu 18.04
in VirtualBox
:
Received signal 11 SEGV_MAPERR 000000000000
#0 0x7faa83f029a5 <unknown>
#1 0x7faa82c42501 <unknown>
#2 0x7faa83f02d3d <unknown>
#3 0x7faa9228a890 <unknown>
r8: 0000000000000001 r9: 0000000002d5d3d0 r10: 0000000000000002 r11: 00007faa8ec4a000
r12: 0000000002d386b0 r13: 0000000002d59b50 r14: 0000000000000000 r15: 00007faa8ed3b280
di: 0000000000001f01 si: 00007faa8ed3d210 bp: 0000000002d52e40 bx: 0000000000000001
dx: 0000000002e52220 ax: 0000000002e52220 cx: 0000000000000000 sp: 00007ffce38c2b78
ip: 0000000000000000 efl: 0000000000010202 cgf: 002b000000000033 erf: 0000000000000014
trp: 000000000000000e msk: 0000000000000000 cr2: 0000000000000000
[end of stack trace]
Calling _exit(1). Core file will not be generated.
that can be solved by following the advise of dcortesi fixing an 4 year old Ubuntu bug:
if sys.platform.startswith( 'linux' ) :
from OpenGL import GL
Putting it all togehter:
requirements.txt
PyQt5 == 5.10.0
PyOpenGL
plotly
webview.py
import sys
if sys.platform.startswith( 'linux' ) :
from OpenGL import GL
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtCore import QDir, QUrl
import plotly
import plotly.graph_objs as go
sys.argv.append("--disable-web-security")
app = QApplication(sys.argv)
x1 = [10, 3, 4, 5, 20, 4, 3]
trace1 = go.Box(x = x1)
layout = go.Layout(showlegend = True)
data = [trace1]
fig = go.Figure(data=data, layout = layout)
path = QDir.current().filePath('plotly-latest.min.js')
local = QUrl.fromLocalFile(path).toString()
raw_html = '<html><head><meta charset="utf-8" />'
raw_html += '<script src="{}"></script></head>'.format(local)
raw_html += '<body>'
raw_html += plotly.offline.plot(fig, include_plotlyjs=False, output_type='div')
raw_html += '</body></html>'
view = QWebEngineView()
view.setHtml(raw_html)
view.show()
sys.exit(app.exec_())
One can download the the latest plotly.js here. I used plotly.js v1.38.0
for this example.
来源:https://stackoverflow.com/questions/46653337/using-a-local-file-in-html-for-a-pyqt5-webengine