How to make QWebEngineView of PyQt5 able to play audio? - python

I want to play audio on the web use QWebEngineView of PyQt5. This is my code:
import sys
from PyQt5 import QtWebEngineWidgets, QtWidgets
if __name__ == '__main__':
app = QtWidgets.QApplication([])
view = QtWebEngineWidgets.QWebEngineView()
view.settings().setAttribute(QtWebEngineWidgets.QWebEngineSettings.PluginsEnabled, True)
view.settings().setAttribute(QtWebEngineWidgets.QWebEngineSettings.JavascriptEnabled, True)
html = '''
<html>
<audio id="pron" src="http://static.sfdict.com/staticrep/dictaudio/A06/A0612000.mp3"></audio>
<button onclick="document.getElementById('pron').play()">Play!</button>
</html>'''
view.setHtml(html)
view.resize(250, 150)
view.move(300, 300)
view.show()
sys.exit(app.exec_())
But when I click the Play button, the audio not play. What's wrong with me?

QWebEngineView doesn't support mp3 playback by default , at least on Win7 as I've tested . If you change your mp3 url to a ogg one(ogg format is supported by default through QWebEngineView ), e.g.
https://upload.wikimedia.org/wikipedia/commons/5/5a/Nl-URL%27s.ogg
then your example would work !
As I searched web, I found the only way to enable the mp3 playback is to compile our own Qt webengine, someone told me the way to do it as following ,
Compile your own Qt (including QtWebEngine), then compile PyQt and
when calling its configure.py, use --qmake to pass the path to the
correct qmake executable.
If anyone interests in compiling Qt webengine, these information may be helpful
How to compile Qt webengine (5.11) on Windows with proprietary codecs
Unable to get mp3 support with QtWebEngine

Related

Pyqt5 Mediaplayer in windows: limited to wmv?

I would like to have video preview in my Qt GUI and I was very happy to see that PyQt5 supports QMediaPlayer.
I found several basic examples here on SO, this one here below is just one:
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtMultimedia import *
from PyQt5.QtMultimediaWidgets import *
class VideoPlayer(QWidget):
def __init__(self, parent=None):
super(VideoPlayer, self).__init__(parent)
videoItem = QGraphicsVideoItem()
videoItem.setSize(QSizeF(640, 480))
scene = QGraphicsScene(self)
scene.addItem(videoItem)
graphicsView = QGraphicsView(scene)
layout = QVBoxLayout()
layout.addWidget(graphicsView)
self.setLayout(layout)
self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
self.mediaPlayer.setVideoOutput(videoItem)
def keyPressEvent(self, e):
if e.key() == Qt.Key_L:
print('loading')
self.load()
if e.key() == Qt.Key_P:
print('playing')
self.mediaPlayer.play()
print('state: ' + str(self.mediaPlayer.state()))
print('mediaStatus: ' + str(self.mediaPlayer.mediaStatus()))
print('error: ' + str(self.mediaPlayer.error()))
print('------------------------')
def load(self):
# H264 MPEG4 AVC not working
file = 'C:/Users/Antonio/Videos/test.wmv'
local = QUrl.fromLocalFile(file)
media = QMediaContent(local)
self.mediaPlayer.setMedia(media)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
player = VideoPlayer()
player.show()
sys.exit(app.exec_())
The videos I would like to preview are generally encoded with H264 MPEG4 AVC and I can watch them on the pc using VLC for example. But when I try to open the same video with the script above, I get an InvalidMedia as error message.
I tried to convert the video in WMV+WMA using VLC and then it works as expected.
Reading a bit on the Qt Documentation (see here) I have the impression that on windows only WMF files are supported. Is this true?
Is there a possibility to extend QMediaPlayer to a larger family of formats via the installation of a codec bundle?
If yes, how can I make aware my pyqt5 installation where to find the relevant codecs?
Thanks in advance
cheers
Qt uses the DirectShow backend on Windows, which, by defauilt, only supports the proprietary MS formats. For non-native formats, users must always install extra codecs, unless the applications they're using bundle them themselves. Qt completely relies on the capabilities of the platform backend, so you'll almost certainly have to install a third-party codec pack if you want to support a wider range of popular formats on Windows.

Remove Logs from PyQt5 Browser on Console

I have a PyQt5 application Virtual Desktop that has a built-in browser. When I use the browser, I get JS errors from the browser similar to how Chrome puts JS and HTML errors in the "Web Inspector". How do I get rid of those errors.
To replicate the errors, download Virtual Desktop and install PyQt from PYPI. You'll need to run main.py, select a QStyle, and click on the Browser (next to the power button). Go to any website (google for example) and switch back to your console. You will notice that the console is populated with JS errors.
I do not observe the problem when using your project but I had this problem before and the solution was to write the javaScriptConsoleMessage() method, eliminating the default behavior.
from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets
class WebEnginePage(QtWebEngineWidgets.QWebEnginePage):
def javaScriptConsoleMessage(self, level, msg, line, sourceID):
pass
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
view = QtWebEngineWidgets.QWebEngineView()
page = WebEnginePage(view)
view.setPage(page)
view.load(QtCore.QUrl("https://www.google.com/"))
view.show()
sys.exit(app.exec_())

How can I append html to my QWebEngineView

So in PyQt4 you could do something like this to append html to your page:
webView.page().mainFrame().documentElement().appendInside(some_html)
I was trying to find similar functionality in PyQt5's QWebEngineView but i couldn't find anything useful.
My problem is that i want to load many html files on one page, and it takes like 10 seconds to do that(means that main GUI thread is blocked during that 10 seconds, and my application is unresponsive).
So my solution was to display first 5, and when user presses the button, it loads next 5(with technique described above), and so on.
So my question is: Does QWebEngineView has this functionality, and is there some other way to deal with big or many html files in QWebEngineView.
documentElement() is a QWebElement and according to the docs is not available in Qt WebEngine.
The documentation recommends using javascript to replace this type of tasks, for example the following code adds html to the QwebEngineView:
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtCore import QTimer, QDateTime
html = '''
<html>
<header><title>This is title</title></header>
<body>
Hello world
</body>
</html>
'''
def append():
some_html = "<p>{}</p>".format(QDateTime.currentDateTime().toString())
page.runJavaScript("document.body.innerHTML += '{}'".format(some_html))
app = QApplication(sys.argv)
view = QWebEngineView()
timer = QTimer()
timer.timeout.connect(append)
page = view.page()
page.loadFinished.connect(lambda: timer.start(1000))
page.setHtml(html)
view.show()
sys.exit(app.exec_())

Qt Designer set "View Code" to always show Python code

When I click "View Code" in Qt Designer (PyQt4), it tries to show the C++ code.
So, the workaround is to run:
pyuic4.bat test.ui > test.py
to convert the file to .py.
Is there a way to execute the above workaround every time "View Code" is clicked or should I have to always perform it manually?
The answer by #WithMetta in the duplicate solved my problem.
I personally load those ui files on the fly without generating python code:
something like this works for me:
import sys
from PyQt4 import QtCore,QtGui,uic
form_class, base_class = uic.loadUiType("unnamed.ui")
class MyWidget (QtGui.QWidget, form_class):
def __init__(self,parent=None,selected=[],flag=0,*args):
QtGui.QWidget.__init__(self,parent,*args)
self.setupUi(self)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
form = MyWidget(None)
form.show()
app.exec_()

Linking a qtDesigner .ui file to python/pyqt?

So if I go into QtDesigner and build a UI, it'll be saved as a .ui file. How can I make this as a python file or use this in python?
Another way to use .ui in your code is:
from PyQt4 import QtCore, QtGui, uic
class MyWidget(QtGui.QWidget)
...
#somewhere in constructor:
uic.loadUi('MyWidget.ui', self)
both approaches are good. Do not forget, that if you use Qt resource files (extremely useful) for icons and so on, you must compile it too:
pyrcc4.exe -o ui/images_rc.py ui/images/images.qrc
Note, when uic compiles interface, it adds 'import images_rc' at the end of .py file, so you must compile resources into the file with this name, or rename it in generated code.
Combining Max's answer and Shriramana Sharma's mailing list post, I built a small working example for loading a mywindow.ui file containing a QMainWindow (so just choose to create a Main Window in Qt Designer's File-New dialog).
This is the code that loads it:
import sys
from PyQt4 import QtGui, uic
class MyWindow(QtGui.QMainWindow):
def __init__(self):
super(MyWindow, self).__init__()
uic.loadUi('mywindow.ui', self)
self.show()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = MyWindow()
sys.exit(app.exec_())
You need to generate a python file from your ui file with the pyuic tool (site-packages\pyqt4\bin)
pyuic form1.ui > form1.py
with pyqt4
pyuic4.bat form1.ui > form1.py
Then you can import the form1 into your script.
I found this article very helpful.
http://talk.maemo.org/archive/index.php/t-43663.html
I'll briefly describe the actions to create and change .ui file to .py file, taken from that article.
Start Qt Designer from your start menu.
From "New Form" window, create "Main Window"
From "Display Widgets" towards the bottom of your "Widget Box Menu" on the left hand side
add a "Label Widget". (Click Drag and Drop)
Double click on the newly added Label Widget to change its name to "Hello World"
at this point you can use Control + R hotkey to see how it will look.
Add buttons or text or other widgets by drag and drop if you want.
Now save your form.. File->Save As-> "Hello World.ui" (Control + S will also bring up
the "Save As" option) Keep note of the directory where you saved your "Hello World" .ui
file. (I saved mine in (C:) for convenience)
The file is created and saved, now we will Generate the Python code from it using pyuic!
From your start menu open a command window.
Now "cd" into the directory where you saved your "Hello World.ui" For me i just had to
"cd\" and was at my "C:>" prompt, where my "Hello World.ui" was saved to.
When you get to the directory where your file is stored type the following.
pyuic4 -x helloworld.ui -o helloworld.py
Congratulations!! You now have a python Qt4 GUI application!!
Double click your helloworld.py file to run it. ( I use pyscripter and upon double click
it opens in pyscripter, then i "run" the file from there)
Hope this helps someone.
You can also use uic in PyQt5 with the following code.
from PyQt5 import uic, QtWidgets
import sys
class Ui(QtWidgets.QDialog):
def __init__(self):
super(Ui, self).__init__()
uic.loadUi('SomeUi.ui', self)
self.show()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Ui()
sys.exit(app.exec_())
The cleaner way in my opinion is to first export to .py as aforementioned:
pyuic4 foo.ui > foo.py
And then use it inside your code (e.g main.py), like:
from foo import Ui_MyWindow
class MyWindow(QtGui.QDialog):
def __init__(self):
super(MyWindow, self).__init__()
self.ui = Ui_MyWindow()
self.ui.setupUi(self)
# go on setting up your handlers like:
# self.ui.okButton.clicked.connect(function_name)
# etc...
def main():
app = QtGui.QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
This way gives the ability to other people who don't use qt-designer to read the code, and also keeps your functionality code outside foo.py that could be overwritten by designer. You just reference ui through MyWindow class as seen above.
You can convert your .ui files to an executable python file using the below command..
pyuic4 -x form1.ui > form1.py
Now you can straightaway execute the python file as
python3(whatever version) form1.py
You can import this file and you can use it.
you can compile the ui files like this
pyuic4 -x helloworld.ui -o helloworld.py
In order to compile .ui files to .py files, I did:
python pyuic.py form1.ui > form1.py
Att.
in pyqt5 to convert from a ui file to .py file
pyuic5.exe youruifile.ui -o outputpyfile.py -x
(November 2020) This worked for me (UBUNTU 20.04):
pyuic5 /home/someuser/Documents/untitled.ui > /home/someuser/Documents/untitled.py
Using Anaconda3 (September 2018) and QT designer 5.9.5.
In QT designer, save your file as ui.
Open Anaconda prompt. Search for your file: cd C:.... (copy/paste the access path of your file).
Then write: pyuic5 -x helloworld.ui -o helloworld.py (helloworld = name of your file). Enter.
Launch Spyder. Open your file .py.

Categories