在Qt的(现已弃用) QWebPage
课程中,每当html内容发出一个信号 contentsChanged()
用户编辑页面或以编程方式更改的页面更改了网页。在较新的QtWebEnginePage
类中,似乎不是等效信号。鉴于从Qt应用程序使网页可编辑的方法已从QWebPage::setContentEditable
方法更改为本机html5 javascript contenteditable
,这并不令我感到惊讶。
我的问题:
有没有办法去"听" QtWebEnginePage
内容更改?这是我现在以某种方式从javascript处理的东西吗?
请注意,我查看了Qt提供的移植信息,但没有发现任何令我印象深刻的内容......
答案 0 :(得分:0)
不幸的是,与QtWebEngine
相比,QtWebKit
与其他Qt设施的整合程度更差,更差。 QtWebKit
能够开箱即用的很多东西只能通过QtWebEngine
的JavaScript技巧来实现。我能够在自己的项目中解决这个特殊问题,但这并不容易。
首先,我必须通过QWebChannel
设置C ++代码和JavaScript代码之间的交互。在这个答案中涵盖的主题太大了,但从好的方面来看,关于此的文档或多或少都是好的:请参阅Qt WebChannel JavaScript API及其examples。最后,从C ++代码开始,您应该可以执行
webChannel->registerObject(QStringLiteral("myObject"), myObject);
其中webChannel
是指向QWebChannel
的指针,而myObject
是指向具有公共插槽的QObject
子类的指针。此操作将允许JavaScript代码调用myObject
的公共槽,从而实现JavaScript和C ++之间的连接。
JavaScript用于跟踪DOM更改的“本机”解决方案是MutationObserver。它是一个实例化的JavaScript对象,用于侦听DOM更改。在每个DOM突变上,观察者调用构造时提供给它的回调函数。为了通知C ++代码中DOM的变化,回调应该调用暴露给JavaScript的某个对象的槽。在此插槽中的C ++代码中,您可以根据需要对内容更改做出反应 - 如果C ++代码的多个部分可能要订阅contentsChanged
信号,请为它们提供此类信号,从插槽中发出myObject
。
以下是JavaScript端MutationObserver
设置的简单示例:
var observer = MutationObserver(function(mutations, observer) {
myObject.onContentChanged();
});
observer.start = function() {
this.observe(document, {
subtree: true,
attributes: true,
childList: true,
characterData: true,
characterDataOldValue: true
});
}
observer.stop = function() {
this.disconnect();
}
虽然设置此方法比使用QtWebKit
的{{1}}信号要复杂得多,但在一天结束时我发现它更灵活,因为contentsChanged
你可以看到完全在DOM中发生了哪些变化并进行了一些高级处理: