Using a local file in html for a PyQt5 webengine

拟墨画扇 提交于 2020-03-15 05:50:15

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!