dliv dliv - 23 days ago 6
Python Question

PyQt5 equivalent of QtWebKitWidgets.QWebView.page.mainFrame() for QtWebEngineWidgets.QWebEngineView()?

I am very new to PyQt and started to play around with the following code (which originally comes from this blog post):

# Create an application
app = QApplication([])

# And a window
win = QWidget()
win.setWindowTitle('QWebView Interactive Demo')

# And give it a layout
layout = QVBoxLayout()
win.setLayout(layout)

# Create and fill a QWebView
view = QWebView()
view.setHtml('''
<html>
<head>
<title>A Demo Page</title>

<script language="javascript">
// Completes the full-name control and
// shows the submit button
function completeAndReturnName() {
var fname = document.getElementById('fname').value;
var lname = document.getElementById('lname').value;
var full = fname + ' ' + lname;

document.getElementById('fullname').value = full;
document.getElementById('submit-btn').style.display = 'block';

return full;
}
</script>
</head>

<body>
<form>
<label for="fname">First name:</label>
<input type="text" name="fname" id="fname"></input>
<br />
<label for="lname">Last name:</label>
<input type="text" name="lname" id="lname"></input>
<br />
<label for="fullname">Full name:</label>
<input disabled type="text" name="fullname" id="fullname"></input>
<br />
<input style="display: none;" type="submit" id="submit-btn"></input>
</form>
</body>
</html>
''')

# A button to call our JavaScript
button = QPushButton('Set Full Name')

# Interact with the HTML page by calling the completeAndReturnName
# function; print its return value to the console
def complete_name():
frame = view.page().mainFrame()
print frame.evaluateJavaScript('completeAndReturnName();')

# Connect 'complete_name' to the button's 'clicked' signal
button.clicked.connect(complete_name)

# Add the QWebView and button to the layout
layout.addWidget(view)
layout.addWidget(button)

# Show the window and run the app
win.show()
app.exec_()


I made some slight changes in order to try to make it run with the latest pyqt5 version, but I don't understand how I should change

frame = view.page().mainFrame()


in order to make the script run without errors. Here is the code I have so far:

from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5 import QtWebEngineWidgets

# Create an application
app = QtWidgets.QApplication([])

# And a window5
win = QtWidgets.QWidget()
win.setWindowTitle('QWebView Interactive Demo')

# And give it a layout
layout = QtWidgets.QVBoxLayout()
win.setLayout(layout)

# Create and fill a QWebView
#view = QtWebKitWidgets.QWebView() # depecated?
view = QtWebEngineWidgets.QWebEngineView()
view.setHtml('''
<html>
<head>
<title>A Demo Page</title>

<script language="javascript">
// Completes the full-name control and
// shows the submit button
function completeAndReturnName() {
var fname = document.getElementById('fname').value;
var lname = document.getElementById('lname').value;
var full = fname + ' ' + lname;

document.getElementById('fullname').value = full;
document.getElementById('submit-btn').style.display = 'block';

return full;
}
</script>
</head>

<body>
<form>
<label for="fname">First name:</label>
<input type="text" name="fname" id="fname"></input>
<br />
<label for="lname">Last name:</label>
<input type="text" name="lname" id="lname"></input>
<br />
<label for="fullname">Full name:</label>
<input disabled type="text" name="fullname" id="fullname"></input>
<br />
<input style="display: none;" type="submit" id="submit-btn"></input>
</form>
</body>
</html>
''')

# A button to call our JavaScript
button = QtWidgets.QPushButton('Set Full Name')

# Interact with the HTML page by calling the completeAndReturnName
# function; print its return value to the console
def complete_name():
frame = view.page().mainFrame() # THIS raises an error. I'm stuck here.

print(frame.evaluateJavaScript('completeAndReturnName();'))

# Connect 'complete_name' to the button's 'clicked' signal
button.clicked.connect(complete_name)

# Add the QWebView and button to the layout
layout.addWidget(view)
layout.addWidget(button)

# Show the window and run the app
win.show()
app.exec_()


I have seen this post, which I thought might help, but unfortunately I'm still stuck with it. Does anyone know how to make this work with the latest PyQt5 version? Help would be very much appreciated.

Answer

There is nothing equivalent to the Qt WebKit QWebFrame class in Qt Web Engine. Frames are just considered part of the content, so there are no dedicated APIs for dealing with them - there is just a single QWebEnginePage, which provides access to the whole web document.

There is also no evaluateJavaScript method. Instead, there is an asynchronous runJavaScript method, which needs a callback to receive the result. So your code should be re-written like this:

def js_callback(result):
    print(result)

def complete_name():
    view.page().runJavaScript('completeAndReturnName();', js_callback)
Comments