PySide2 和支持 addToJavaScriptWindowObject

Posted

技术标签:

【中文标题】PySide2 和支持 addToJavaScriptWindowObject【英文标题】:PySide2 and supporting addToJavaScriptWindowObject 【发布时间】:2018-06-24 15:17:29 【问题描述】:

我正在尝试将 PySide 应用程序版本 #1 移植到 PySide2 并努力寻找移植以下代码 sn-p 的解决方案:

class AppManager(QtCore.QObject):
    '''
    methods of AppObject will be available from javascript
    '''
    def __init__(self, webview):
        QtCore.QObject.__init__(self)


class WebView(QWebEngineView):
    def __init__(self, parent=None):
        QWebEngineView.__init__(self, parent)
        self.setPage(WebEnginePage(self))

    def contextMenuEvent(self, event):
        pass


class AppWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.view = WebView(self)
        self.page = self.view.page()
        self.app_manager = AppManager(self.view)
        self.page.mainFrame().addToJavaScriptWindowObject('app_manager', self.app_manager)
        # ERROR in above line !!!

我在文档中找不到我必须找到可能的修复方法

【问题讨论】:

QWebChannel 【参考方案1】:

你必须使用QWebChannel,为此你必须下载qwebchannel.js(链接指向qwebchannel.js for Qt 5.12,不同版本更改github分支) .

在下面的代码中我展示了一个例子:

.
├── index.html
├── main.py
└── qwebchannel.js

ma​​in.py

import sys

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


class WebEnginePage(QtWebEngineWidgets.QWebEnginePage):
    pass

class AppManager(QtCore.QObject):
    textChanged = QtCore.Signal(str)
    def __init__(self, webview):
        QtCore.QObject.__init__(self)
        self.m_text = ""

        timer = QtCore.QTimer(self)
        timer.timeout.connect(self.on_timeout)
        timer.start(1000)

    def on_timeout(self):
        self.text  = QtCore.QDateTime.currentDateTime().toString()

    @QtCore.Property(str, notify=textChanged)
    def text(self):
        return self.m_text

    @text.setter
    def setText(self, text):
        if self.m_text == text:
            return
        self.m_text = text
        self.textChanged.emit(self.m_text)


class WebView(QtWebEngineWidgets.QWebEngineView):
    def __init__(self, parent=None):
        QtWebEngineWidgets.QWebEngineView.__init__(self, parent)
        self.setPage(WebEnginePage(self))

    def contextMenuEvent(self, event):
        pass


class AppWindow(QtWidgets.QMainWindow):
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        self.view = WebView(self)
        self.page = self.view.page()
        self.app_manager = AppManager(self.view)
        channel = QtWebChannel.QWebChannel(self)
        self.page.setWebChannel(channel)
        channel.registerObject("app_manager", self.app_manager)
        self.view.load(QtCore.QUrl.fromLocalFile(QtCore.QDir.current().filePath("index.html")))
        self.setCentralWidget(self.view)

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    w = AppWindow()
    w.show()
    sys.exit(app.exec_())

index.html

<html>
<head>
    <script type="text/javascript" src="./qwebchannel.js"></script>
</head>
<header><title>This is title</title></header>
<body>

<p id="output"></p>

<script type="text/javascript">
    window.onload = function() 
        new QWebChannel(qt.webChannelTransport, function (channel) 
            window.app_manager = channel.objects.app_manager;
            console.log(app_manager);

            app_manager.textChanged.connect(function(message) 
                document.getElementById("output").innerHTML = "Received message: " + message;
            );

        );
    
</script> 
</body>
</html>

【讨论】:

在这种情况下,使用建议的 qwebchannel.js -文件对于基于软件创建者来说是免费的吗?还是应该订购付费版的 PyQT? @YoungMaster 它是 Qt 的一部分:doc.qt.io/qt-5.9/…,许可证在文件中,所以我建议阅读它。

以上是关于PySide2 和支持 addToJavaScriptWindowObject的主要内容,如果未能解决你的问题,请参考以下文章

解决 ModuleNotFoundError: No module named ‘PySide2.QtUiTools‘

解决 ModuleNotFoundError: No module named ‘PySide2.QtUiTools‘

解决 ModuleNotFoundError: No module named ‘PySide2.QtUiTools‘

PySide2 与 Pyqt5 的区别

同时安装pyside2和pyside6

QOpenGLFunctions 和 PySide2