从 js QWebEngineView 获取变量到 python

Posted

技术标签:

【中文标题】从 js QWebEngineView 获取变量到 python【英文标题】:Get variable from js QWebEngineView to python 【发布时间】:2019-11-19 18:50:20 【问题描述】:

我正在使用 PyQt5 和 python3 的 QT 设计器,我正在使用 QWebEngineView 加载 html 和 js。 html里面有一个输入和一个按钮,按下按钮执行一个js函数,将输入的值保存在一个变量中。

如何从 js 中获取该变量并转到 python?

代码 HTML:

<input id="input">
<button id="button" onclick="x()"></button>
<script>
function x() 
    var a = document.getElementById("input").value;

</script>

代码 Python:

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(449, 391)
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap("favicon.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        Form.setWindowIcon(icon)
        Form.setWindowOpacity(0.8)
        self.webEngineView = QtWebEngineWidgets.QWebEngineView(Form)
        self.webEngineView.setGeometry(QtCore.QRect(-1, 0, 451, 391))
        self.webEngineView.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
        self.webEngineView.setStyleSheet("width: 100%")
        self.webEngineView.setUrl(QtCore.QUrl("file:///C:/xampp/htdocs/indexx.html"))
        self.webEngineView.setObjectName("webEngineView")
        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Bancus"))
from PyQt5 import QtWebEngineWidgets

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Form = QtWidgets.QWidget()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())

【问题讨论】:

self.webEngineView.page().runjavascript(js_code, callback). 代码如何操作? 【参考方案1】:

您的问题的描述不清楚,但假设您想在按下按钮时获取放置在 python 输入中的文本并且您可以修改 HTML,那么可能的解决方案是使用 QWebChannel:

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


class Backend(QtCore.QObject):
    valueChanged = QtCore.pyqtSignal(str)

    def __init__(self, parent=None):
        super().__init__(parent)
        self._value = ""

    @QtCore.pyqtProperty(str)
    def value(self):
        return self._value

    @value.setter
    def value(self, v):
        self._value = v
        self.valueChanged.emit(v)


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.webEngineView = QtWebEngineWidgets.QWebEngineView()
        self.label = QtWidgets.QLabel(alignment=QtCore.Qt.AlignCenter)

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(self.webEngineView, stretch=1)
        lay.addWidget(self.label, stretch=1)

        backend = Backend(self)
        backend.valueChanged.connect(self.label.setText)
        backend.valueChanged.connect(self.foo_function)
        self.channel = QtWebChannel.QWebChannel()
        self.channel.registerObject("backend", backend)
        self.webEngineView.page().setWebChannel(self.channel)

        path = "C:/xampp/htdocs/indexx.html"
        self.webEngineView.setUrl(QtCore.QUrl.fromLocalFile(path))

    @QtCore.pyqtSlot(str)
    def foo_function(self, value):
        print(value)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>        
        <script src="qrc:///qtwebchannel/qwebchannel.js"></script>
    </head>
    <body> 
         <input id="input">
         <button id="button">Click me</button>
    </body>
    <script>
        var backend = null;
        new QWebChannel(qt.webChannelTransport, function (channel) 
            backend = channel.objects.backend;
        );
        document.getElementById("button").addEventListener("click", function()
            backend.value = document.getElementById("input").value;
        );
    </script>
</html>

如果我认为某处有问题,请随时指出以提供合适的解决方案。

【讨论】:

我想点击按钮执行一个使用输入文本作为参数的python函数 @Oni 我已经修改了我的代码,添加了按下按钮时将调用的函数 foo_function,在我的示例中它会打印该值。 抱歉耽搁了,但这正是我所需要的。谢谢+1

以上是关于从 js QWebEngineView 获取变量到 python的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Qt QWebEngineView 获取 HTTP 状态码?

如何将 swf 文件从内存加载到 QWebEngineView

QWebEngineView 在外部浏览器中打开

从 QWebEngineView 自动登录到网站

如何使用 QWebEngineView 和 qtwebchannel.js 逐步加载 javascript?

qwebengineview如何让js调用qt中的方法