从 JavaScript 调用 Qt 插槽

Posted

技术标签:

【中文标题】从 JavaScript 调用 Qt 插槽【英文标题】:Calling Qt slot from JavaScript 【发布时间】:2018-02-26 06:42:23 【问题描述】:

我正在使用 QWebEnginePage 类来呈现我的网页。我需要实现回调函数。所以首先我想在 JS 中注册我的插槽,并在需要时从 JS 调用这个插槽(例如,在网页上单击按钮之后)。我尝试像there 那样做,但这不是我需要的,因为它仅说明从 Qt 调用 JS 函数并接收结果,但我需要回调。可以实现吗?

在 Qt 的早期版本中有一个模块 qtwebkit,我的目标可以像 there 中描述的那样使用 addTojavascriptWindowObject 方法来实现。但是如何使用没有那个甚至类似方法的 qtwebenginewidgets 模块来做到这一点?

【问题讨论】:

【参考方案1】:

在QWebEngine 中,您可以使用QWebChannel 与您的JS 进行通信

创建一个代理对象从 JS 与 Qt 通信

// This Object will be registered in the web channel
class MyJSObj : public QObject

 Q_OBJECT
public:
   MyJSObj(QObject * poParent = Q_NULLPTR);

   Q_INVOKABLE int foo(); // call from JS
;

在您的 cpp 代码中

// Create proxy object
m_poMyJSObj = new MyJSObj(this);

// Create channel
m_poWebView = new QWebEngineView(this);
QWebChannel * poChannel = new QWebChannel();
m_poWebView->page()->setWebChannel(poChannel);

// Register your proxy object
const QString oJSObjectName = "mJSQtObject"; // use in JS to call Qt functions
poChannel->registerObject(oJSObjectName, m_poMyJSObj);

在 JS 中

new QWebChannel(qt.webChannelTransport, function (channel) 
            // now you retrieve your object
            var JSQtObject = channel.objects.mJSQtObject;
            // call Qt function from JS
            var qtValue = JSQtObject.foo();
        );

请注意,您必须在 html 端包含 qwebchannel.js

【讨论】:

以上是关于从 JavaScript 调用 Qt 插槽的主要内容,如果未能解决你的问题,请参考以下文章

Qt 插槽同时断开连接并从不同线程调用

Qt 插槽未被调用

未连接的 Qt 插槽被调用

Qt 插槽,调用没有匹配函数

未调用 Qt moveToThread 插槽

发出 Qt 信号但从未调用过插槽