QWebEnginePage与javascript交互不起作用?

2024-09-27 09:37:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我不熟悉javascriptQWebEnginePage
当我设置self.content.setText('text')内容时,QWebEngineView内容没有改变吗

python代码

class Document(QObject):
    textChanged = pyqtSignal(str)
    def __init__(self):
        super().__init__()
        self.text  = ''
    
    def setText(self, text):
        self.text = text
        self.textChanged.emit(text)
        print('emit')

class Demo(QWebEngineView):
    def __init__(self):
        super().__init__()
        self.content = Document()
        page = self.page()
        channel = QWebChannel()
        channel.registerObject('content', self.content)
        page.setWebChannel(channel)
        with open('index.html') as f:
            self.setHtml(f.read())

        self.content.setText('text')

app = QApplication([])
demo = Demo()
demo.resize(500, 400)
demo.show()
app.exec()

索引html:

<!doctype html>
<html lang="en">
<meta charset="utf-8">
<head>
    <script src="qwebchannel.js"></script>
</head>
<body>
<div id="placeholder">22</div>
<script>
    'use strict';

    var placeholder = document.getElementById('placeholder');

    var updateText = function (text) {
        placeholder.innerHTML = text;
        console.log(text);
    }

    new QWebChannel(qt.webChannelTransport,
        function (channel) {
            var content = channel.objects.content;
            updateText(content.text);
            content.textChanged.connect(updateText);
        }
    );
</script>
</body>
</html>


Tags: textselfinitdemovardefhtmlpage
1条回答
网友
1楼 · 发布于 2024-09-27 09:37:14

您有以下错误:

  • channel是一个局部变量,它将在“Demo”构造函数完成后立即删除,它是Python和Javascript通信之间的中介。解决方案是通过向其传递父级(Qt样式)或使其成为类的属性来延长生命周期

  • 在.html中,您试图包括qwebchannel.js,但通常应使用<script src="qrc:///qtwebchannel/qwebchannel.js"></script>

  • 如果将QObject导出到javascript,则只导出Q属性、QSlot和QSignals,因为QWebChannel使用QMetaObject指令属性,但“text”两者都不是,因此在javascript中未定义。解决方案是将其作为pyqtProperty公开

import os
from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject, QUrl
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWebChannel import QWebChannel


CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))


class Document(QObject):
    textChanged = pyqtSignal(str)

    def __init__(self):
        super().__init__()
        self._text = ""

    def text(self):
        return self._text

    def setText(self, text):
        self._text = text
        self.textChanged.emit(text)
        print("emit")

    text = pyqtProperty(str, fget=text, fset=setText, notify=textChanged)


class Demo(QWebEngineView):
    def __init__(self):
        super().__init__()

        self.content = Document()

        channel = QWebChannel(self)
        channel.registerObject("content", self.content)
        self.page().setWebChannel(channel)

        filename = os.path.join(CURRENT_DIR, "index.html")
        self.load(QUrl.fromLocalFile(filename))

        self.content.setText("text")


def main():
    app = QApplication([])
    demo = Demo()
    demo.resize(500, 400)
    demo.show()
    app.exec()


if __name__ == "__main__":
    main()
<!doctype html>
<html lang="en">
<meta charset="utf-8">
<head>
    <script src="qrc:///qtwebchannel/qwebchannel.js"></script>
</head>
<body>
<div id="placeholder">22</div>
<script>
    'use strict';

    var placeholder = document.getElementById('placeholder');

    var updateText = function (text) {
        placeholder.innerHTML = text;
        console.log(text);
    }

    new QWebChannel(qt.webChannelTransport,
        function (channel) {
            var content = channel.objects.content;
            updateText(content.text);
            content.textChanged.connect(updateText);
        }
    );
</script>
</body>
</html>

相关问题 更多 >

    热门问题