PySide2: How to embed HTML5 video in QWebEngineView - python

I am trying to display a video file inside a PySide2 app I'm writing. That app uses a QWebEngineView and loads a local html file that contains a <video> tag, pointing to a local mov or mp4 file. Somehow I can see the player, but it doesn't load the file.
I've put this little html test page together which loads fine in Chrome, but not in my app. Note that in this file I'm using an online mp4 file, but I've tried both, local and online files, mov and mp4.
<!doctype html>
<html lang="en">
<head>
</head>
<body>
<video width="320" height="240" controls>
<source src="https://archive.org/download/VideoTestFiles/1280X72025FpsPhotoJpeg75.mp4" type="video/mp4" >
</video>
</body>
In my PySide2 app, I'm loading the page like follows:
import os, sys
from PySide2 import QtWidgets
from PySide2.QtWebEngineWidgets import QWebEngineView, QWebEngineSettings
from PySide2.QtCore import QUrl
app = QtWidgets.QApplication(sys.argv)
view = QWebEngineView()
path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "test.html")
view.load(QUrl.fromLocalFile(path))
view.show()
sys.exit(app.exec_())
I have also tried the following settings, none of which seem to help:
view.settings().setAttribute(QWebEngineSettings.PluginsEnabled, True)
view.settings().setAttribute(QWebEngineSettings.JavascriptEnabled, True)
view.settings().setAttribute(QWebEngineSettings.AllowRunningInsecureContent, True)
view.settings().setAttribute(QWebEngineSettings.LocalContentCanAccessFileUrls, True)
view.settings().setAttribute(QWebEngineSettings.LocalContentCanAccessRemoteUrls, True)
Any help appreciated!
Edit:
I just realized: while there is no error in Chrome console, there is an error being displayed in the Python console after closing the app:
[9476:13164:1017/182854.157:ERROR:media_internals.cc(102)] Cannot get RenderProcessHost

Related

Python, PySide6; JS not receiving data from QWebChannel

I've seen many many answers about this question, but still cannot figure it out.
I made two files, one - html with qrc definition + new QWebChannel, and second python file with Object and QWebEngineView.
JS script seems to not working. It doesn't binding channel object to local var.
I've tried many examples from many pages, looking native QT language or C++, I cannot figure it out.
QWebChannel definition and qt object are found.
Maybe something is not ok with PySide6? Please help me figure it out.
My code:
index.html
<head>
<title>Test</title>
<script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script>
<script type="text/javascript">
let dataSource = null
window.onload = function () {
alert('before') //works
new QWebChannel(qt.webChannelTransport, function (channel) {
alert('inside') //not working
dataSource = channel.objects.backend;
}
);
alert('after') //works
alert(dataSource) //null
}
</script>
</head>
<body>
<p>Hello</p>
</body>
</html>
main.py
import sys, os
from PySide6.QtCore import Signal, QUrl, Slot, QObject
from PySide6.QtWidgets import QMainWindow, QApplication, QVBoxLayout, QWidget
from PySide6.QtWebEngineWidgets import *
from PySide6.QtWebEngineCore import *
from PySide6.QtWebChannel import QWebChannel
class Backend(QObject):
#Slot(result=int)
def getValue(self):
return 1
#Slot(int)
def printValue(self, val):
print(val)
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow,self).__init__(*args, **kwargs)
self.browser = QWebEngineView()
backend = Backend()
channel = QWebChannel()
channel.registerObject("backend", backend)
self.browser.page().setWebChannel(channel)
current_dir = os.path.dirname(os.path.realpath(__file__))
filename = os.path.join(current_dir, "index.html")
url = QUrl.fromLocalFile(filename)
self.browser.load(url)
self.setCentralWidget(self.browser)
self.resize(1200,900)
self.show()
app = QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec())
UPDATE:
I extended view, added dev tool and jquery to check objects - that what I have:
UPDATE 2:
I removed PySide6, installed PyQt5 and used example from here:
How to receive data from python to js using QWebChannel?
Everything works :/
I spend whole day to figure it out. I don't know why it's not working.

PyQt5: Reference local copy of Mathjax in QWebEngineView

Following this post and the mathjax 3 documentation, I am trying to render a simple html with Mathjax content in PyQt5 using a local copy of the mathjax repo.
The main directory contains the notebook from which the following code is executed, a "mathjax" folder containing the content of the repo (especially the es5 folder). Notice that I tried with 2 paths to the js (comment toward the top) :
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtCore import QUrl
import os
# <script type="text/javascript" src="file:///Users/mocquin/.../mathjax/es5/tex-chtml-full.js">
pageSource = """
<html><head>
<script type="text/javascript" src="./mathjax/es5/tex-chtml-full.js">
</script></head>
<body>
<p><mathjax style="font-size:2.3em">$$u = \int_{-\infty}^{\infty}(awesome)\cdot du$$</mathjax></p>
</body></html>
"""
app = QApplication(sys.argv)
webView = QWebEngineView()
webView.setHtml(pageSource, baseUrl=QUrl(os.path.abspath('')))
webView.show()
sys.exit(app.exec_())
But this only renders the content without the "latex parsing"
What am I missing so that the mathjax is indeed linked to the html ?
The problem with your example is that you aren't using the correct format for the src path and base url. The src path must be a plain relative path, and the base url should be a backslash-terminated absolute path to the directory containing the mathjax directory.
Assuming the mathjax directory is in the same directory as the python script, the following should work correctly (at least, it does for me):
import sys, os
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineWidgets import QWebEngineView
pageSource = """
<html><head>
<script type="text/javascript" async src="mathjax/es5/tex-chtml-full.js"></script>
</head><body>
<p><mathjax style="font-size:2.3em">$$u = \int_{-\infty}^{\infty}(awesome)\cdot du$$</mathjax></p>
</body></html>
"""
baseurl = QUrl.fromLocalFile(os.path.dirname(os.path.abspath(__file__)) + '/')
print(f'BASEURL: {baseurl.toString()!r}') # BASEURL: 'file:///home/tmp/test/'
app = QApplication(sys.argv)
webView = QWebEngineView()
webView.setHtml(pageSource, baseUrl=baseurl)
webView.show()
sys.exit(app.exec_())

Incorrect rendering of Javascript by PyQt5 QWebEngine

I'm building a browser using PyQt5. It's a rather huge code, but this is the main problem I'm facing. The code is this:
import sys
from PyQt5.QtCore import QUrl
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWidgets import QApplication, QMainWindow
app = QApplication(sys.argv)
web = QWebEngineView()
file = open("example.html", "r")
html = file.read()
web.setHtml(html)
file.close()
web.show()
sys.exit(app.exec_())
The problem is that the rendering is rather strange.Image of the rendering is here.
The contents of the example.html file:
<!DOCTYPE html>
<head><title>JS Example</title></head>
<h1>JS example</h1>
<p><button type = 'button' onclick = "document.getElementById('tobeshown').style.display='block'">Show hidden parts of this page</button></p>
<p id = 'tobeshown' style = "display:none">
Peekaboo!
</p>
<p>
<button type = 'button' onclick="document.getElementById('tobeshown').style.display='none'">Hide it!</button>
</p>
</body>
</html>
The expected output(this is in Mozilla Firefox browser): here
Can anyone tell me why the PyQt5 rendering engine produces those symbols at the top? And what can I do to resolve it? Thank you very much.
So the problem is not WebEngine's rendering but instead Python's reading of a file. Changing the file's encoding to UTF-8 solved the problem for me.

how I use the QTextEdit in pyqt5 to show all style of the html (including the style of css)

Python 3.6 PYQT 5.12.1
I am ready to show the style I need by pyqt5 and I knew that the QTextEdit in pyqt5 can display the html code pretty good (I have some experience in web development), so I decided to use html/css to show my style . However , it may have some problem in showing the code in css . What can I do to let it can show the css/javascript ? If it can‘t , can recommend other methods to modify the style?
It can show some style like width = "100" height = "100" when I code it in the html but not css and some can't display like border-radius:50%;. It won't get any effect when I code the style in css . By the way , I've imported CSS code.
The CSS code do nothing in QTextEdit (but it is ok in html)
.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
class WINDOW(QMainWindow):
def __init__(self):
super().__init__()
self.init()
def init(self):
w_width,w_height,w_x,w_y = 700,640,700,200
self.set_size_pos(w_width,w_height,w_x,w_y);
self.set_message_textedit()
self.message_textedit.setHtml(self.get_html())
self.show()
def set_size_pos(self,width,height,x,y):
'''
set window's width , height and position
'''
self.resize(width,height)
self.move(x,y)
def set_message_textedit(self):
self.message_textedit = QTextEdit(self)
self.message_textedit.setFont(QFont("Microsoft YaHei",12))
self.message_textedit.resize(680,420)
self.message_textedit.move(10,50)
self.message_textedit.setReadOnly(True)
def get_html(self):
html = ""
with open("./chat-style/chat.html","r",encoding = "utf-8") as f:
html = f.read()
return html
if __name__ == '__main__':
app = QApplication(sys.argv)
test = WINDOW()
sys.exit(app.exec_())
.html
<!doctype html>
<html lange="zh-CN">
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="./chat.css">
<script src = "chat.js"></script>
</head>
<body>
<img class = "tx" src="E:\study\assiataant\picture\icon.jpg">
<div>Welcome ~ Don!</div>
</body>
</html>
.css
.tx
{
border-radius:50%;
width: 30;
height: 30;
}
QTextEdit only supports CSS 2.1 as indicated by the docs:
All CSS 2.1 selector classes are supported except pseudo-class selectors such as :first-child, :visited and :hover.
But border-radius was introduced in CSS3. So you can not use it unfortunately. I recommend you read the following link so that you know the allowed tags.
Another alternative is to use QWebEngineView that supports these tags:
*.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import os
import sys
from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
view = QtWebEngineWidgets.QWebEngineView()
file = os.path.join(
os.path.dirname(os.path.realpath(__file__)),
"chat-style/chat.html"
)
view.load(QtCore.QUrl.fromLocalFile(file))
self.setCentralWidget(view)
self.resize(640, 480)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
If you do not have QWebEngineView installed, you must install it with the following command:
python -m pip install PyQtWebEngine

QtWebegnine jstProcess is not defined

I'm trying to open a simple html file (something like this)
<html>
<body>
<h1>hello</h1>
</body>
</html>
which does not have any embedded or external JavaScript, inside QtWebEngine using this code
import sys
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineWidgets import QWebEngineView
class Browser(QWebEngineView):
def __init__(self):
self.view = QWebEngineView.__init__(self)
self.setWindowTitle("Loading ...")
self.titleChanged.connect(self.adjustTitle)
def adjustTitle(self):
self.setWindowTitle(self.title())
if __name__ == "__main__":
app = QApplication(sys.argv)
view = Browser()
view.showMaximized()
url = QUrl.fromLocalFile("simple.html")
view.setUrl(url)
sys.exit(app.exec_())
But when i run it the following error appears in the console
js: Uncaught ReferenceError: jstProcess is not defined
What is jstProcess and how can i define it? (The code works fine if I load some remote resource like bing.com)
Your eg works for me
if give a fully qualified file name for simple as
'/home/me/simple.htm' . Or if simple.htm is in same directory
where I am running the python I do
import sys,os
fname = os.getcwd()+ '/simple.html'
url = QUrl.fromLocalFile(fname)
This is with the pyqt that comes with Debian that I am running
under python 2.

Categories

Resources