Here's my problem: I want to load a local html file into a QWebView in Python.
EDIT: I use PySide as a Qt package.
My code:
class myWindow(QWidget):
def __init__(self, parent=None):
self.view = QWebView(self)
filepath = "file://" + os.path.join(os.path.dirname(__file__), 'googlemap.html')
self.view.load(QUrl(filepath))
This is just showing me a blank widget.
If I change
self.view.load(QUrl(filepath)
by
self.view.load(QUrl("http://www.google.com/"))
It works fine.
However, the file is clearly in the good directory and I can open the same file directly with my browser.
EDIT 2:
The problem appears after an update on my Raspberry Pi 2 (which runs the code above)
Two observations:
path needs to be absolute (not relative)
use QUrl.fromLocalFile(path)
so something like this
file_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "aa.html"))
local_url = QUrl.fromLocalFile(file_path)
browser.load(local_url)
should work.
Full example:
from PyQt4.QtWebKit import QWebView
from PyQt4.QtGui import QApplication
from PyQt4.QtCore import QUrl
import sys
import os
app = QApplication(sys.argv)
browser = QWebView()
file_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "aa.html"))
local_url = QUrl.fromLocalFile(file_path)
browser.load(local_url)
browser.show()
app.exec_()
Related
QSound from pyqt5 has been giving me trouble, some wav files work well. Others cause the Qt app to error and not run. I have with research narrowed the culprit down to the headers of the wav files.
If I open the wav file in Audacity and export it as a wav file... the exported wav file works perfectly. However I need a solution that runs from within my python script.
I am getting my wav files from Watson's Text-To-Speech api, not sure if I can control what headers it includes.
import sys
from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow
from PyQt5.QtCore import Qt
from PyQt5.QtMultimedia import QSound
from ibm_watson import TextToSpeechV1
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator
def list_to_speech(text, language='ja-JP_EmiV3Voice'):
api_key = "my_api_key"
url = "url"
# Set up service
authenticator = IAMAuthenticator(api_key)
# Now TTS service
tts = TextToSpeechV1(authenticator=authenticator)
# Set Service URL
tts.set_service_url(url)
with open('text_to_speech.wav', 'wb') as audio_file:
res = tts.synthesize(text, accept='audio/wav', voice=language).get_result()
audio_file.write(res.content)
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.sound = QSound("text_to_speech.wav")
self.sound.play()
label = QLabel("This PyQt5 window will (try to) play the wav file!")
label.setAlignment(Qt.AlignCenter)
self.setCentralWidget(label)
if __name__ == "__main__":
# the file saved by list_to_speech won't play as QSound(text_to_speech.wav).play()
# (instead it crashes the app before opening)
#
# if I open the text_to_speech.wav file in Audacity and export it with empty headers,
# then comment out next line, it works.
list_to_speech("ありがとう")
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
A possible solution is not to use QSound but rather QMediaPlayer that allows handling other codecs:
import os
import sys
from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow
from PyQt5.QtCore import Qt, QUrl
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
# ...
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
filename = os.path.join(CURRENT_DIR, "text_to_speech.wav")
self.player = QMediaPlayer()
url = QUrl.fromLocalFile(filename)
self.player.setMedia(QMediaContent(url))
self.player.play()
label = QLabel("This PyQt5 window will (try to) play the wav file!")
label.setAlignment(Qt.AlignCenter)
self.setCentralWidget(label)
# ...
Note: Another option is to use another format like mp3.
Is it possible to change the Save/Open/Cancel text of native file dialogs called by Qt, e.g.
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
OpenFile = QFileDialog()
OpenFile.getExistingDirectory()
I've tried following some examples in C++, e.g. this, but it doesn't seem to have any effect. Maybe I'm doing something wrong?
Try it:
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
OpenFile = QFileDialog()
#OpenFile.getExistingDirectory()
OpenFile.setFileMode(QFileDialog.DirectoryOnly)
OpenFile.setLabelText(QFileDialog.Accept, "+Accept+")
OpenFile.setLabelText(QFileDialog.Reject, "-REJECT-")
OpenFile.show()
sys.exit(app.exec_())
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.
how to send an opened file inside the main application to a page in QWebEngineView and handle it by javascript FileReader() function , as it was opened by an html5 file input inside the QWebEngineView
here is a part of my code
# -*- coding: utf-8 -*-
import sys, os
from PyQt5.QtWidgets import ( QApplication, QMainWindow)
from PyQt5.QtCore import QUrl
import PyQt5.QtWebEngineWidgets as QtWebEngineWidgets
import interface
class MyWindow(QMainWindow):
def __init__(self, parent=None):
QMainWindow.__init__(self, parent)
self.ui = interface.Ui_MainWindow()
self.ui.setupUi(self)
web_view = QtWebEngineWidgets.QWebEngineView()
self.web_view = web_view
self.ui.verticalLayout_navigateur.addWidget(web_view)
url = self.local_url("src/index.html")
self.web_view.load(url)
f = open('myfile.json', 'r')
#send f to self.web_view and handle it by javascript FileReader() function
def local_url(self, relativePath):
absolutePath = os.path.abspath(relativePath)
url = QUrl.fromLocalFile(absolutePath)
return url
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
thanks
i found an alternative solution, it's quite simple, instead of sending object file to read with javascript, i have just to read it in the main application and inject the content via a QWebChannel
I would like to use PyQt/QWebview to 1) load a specific url, 2) enter information into a form, 3) click buttons/links. Mechanize does not work because I need an actual browser.
Here's my code:
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
from PyQt4 import QtCore
app = QApplication(sys.argv)
web = QWebView()
web.load(QUrl("https://www.lendingclub.com/account/gotoLogin.action"))
def fillForm():
doc = web.page().mainFrame().documentElement()
user = doc.findFirst("input[id=master_username]")
passwd = doc.findFirst("input[id=master_password]")
user.setAttribute("value", "email#email.com")
passwd.setAttribute("value", "password")
button = doc.findFirst("input[id=master_sign-in-submit]")
button.evaluateJavaScript("click()")
QtCore.QObject.connect(web, QtCore.SIGNAL("loadFinished"), fillForm)
web.show()
sys.exit(app.exec_())
The page loads correctly, but no input is entered and the form is not submitted. Any ideas?
This helped me to make it work:
user.setAttribute("value", "email#email.com")
-->
user.evaluateJavaScript("this.value = 'email#email.com'")
Attribute and property are different things.
One more fix:
click() --> this.click()
For anyone looking to do this with PyQt5, this example may help as several things have changed. Obviously the javascript needs to be adjusted based on the contents of the website.
import os
import sys
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget
from PyQt5.QtCore import QUrl, QEventLoop
from PyQt5.QtWebEngineWidgets import QWebEngineView
class WebPage(QWebEngineView):
def __init__(self):
QWebEngineView.__init__(self)
self.load(QUrl("https://www.url.com"))
self.loadFinished.connect(self._on_load_finished)
def _on_load_finished(self):
print("Finished Loading")
self.page().toHtml(self.Callable)
def Callable(self, html_str):
self.html = html_str
self.page().runJavaScript("document.getElementsByName('loginid')[0].value = 'email#email.com'")
self.page().runJavaScript("document.getElementsByName('password')[0].value = 'test'")
self.page().runJavaScript ("document.getElementById('signin').click()")
if __name__ == "__main__":
app = QApplication(sys.argv)
web = WebPage()
web.show()
sys.exit(app.exec_()) # only need one app, one running event loop
You might be able to do it with Webkit/QWebView but what about using selenium: http://code.google.com/p/selenium/ ? It is designed for exactly this kind of browser automation and has nice python bindings.