2017-08-10 75 views
0

我正在使用QT 5.9 WebEngine框架来显示网页。我在加载时将JavaScript注入页面,并且希望允许javascript能够访问QT对象。QT QWebchannel无法访问CPP对象方法或属性

我得到的JS的QWebchannel回调被调用,但对象的方法和属性是未定义的。

注意:我需要注入所有的JS代码,并不能改变加载页面的HTML代码。这意味着我不能包含任何js脚本,也不能直接在html页面中编写任何js代码。

这里是我的代码:

我创建QWebEnginePage对象与配置文件和注入JS文件如下:

// file: webview.cpp, webview extends **QWebEngineView** 

QWebEngineScript script; 
script.setSourceCode(qwebchannelsource); // source is qwebchannel.js 
script.setInjectionPoint(QWebEngineScript::DocumentCreation); 
profile->scripts()->insert(script); 
QWebEnginePage page* = new QWebEnginePage(profile, this); 

QWebChannel *channel = new QWebChannel(page); 
page->setWebChannel(channel); 
channel->registerObject(QStringLiteral("jshelper"), &JSHelper::instance()); 

JSHelper

class JSHelper : public QObject 
{ 
public: 
    static JSHelper &instance(); 
    QString someString; 
    int someInt; 

    Q_INVOKABLE int getInt(); 
    Q_PROPERTY(int myIntInCppSide READ getInt) 

private: 
    JSHelper(); 
}; 

JS代码

// also injected into the page (like qwebchannel.js) at QWebEngineScript::DocumentReady 

new QWebChannel(qt.webChannelTransport, function (channel) { 
    var jshelper = channel.objects.jshelper; 
    console.warn('qwebchannel triggered'); 

    // do what you gotta do 
    if (jshelper === undefined) { 
     console.warn("jshelper is undefined"); 
    } 
    else { 
     console.warn("jshelper is awesome"); 
    } 

    console.warn("jshelper value of string " + jshelper.somestring); 
    console.warn("jshelper value of int " + jshelper.myIntInCppSide); 
    jshelper.myIntInCppSide(function (n) { 
     console.warn("jshelper value of int " + n); 
    }); 
}); 

我的输出:

qwebchannel triggered" 
jshelper is awesome" 
jshelper value of string undefined" 
jshelper value of int undefined" 
Uncaught TypeError: jshelper.myIntInCppSide is not a function" 

正如你可以看到我已经从几个答案尝试了各种建议,但似乎没有解决我的问题,该函数不存在。 即使在使用远程调试时,我可以看到jshelper是QObject类型,但它没有我的类的属性和方法。

QT QWebEnginePage::setWebChannel() transport object

Undefined properties and return types when using QWebChannel

+0

您是否曾尝试在'JSHelpre'类声明的开头插入'Q_OBJECT'宏? – Dmitry

+0

是的,我得到'JSHelper的vtable的未定义引用'编译错误 – Anand

+0

啊,我错过了你有默认的构造函数私人的事实,这必须是编译错误的原因。你可以检查一下,如果你使默认构造函数为public并使用'Q_OBJECT'宏,会发生什么? – Dmitry

回答

0

JSHelper类错过Q_OBJECT宏。作为official documentation说,

注意,Q_OBJECT宏是强制性的任何对象,该对象实现 信号,槽或属性。您还需要运行源文件上的对象编译器Meta 。我们强烈建议在QObject的所有子类中使用这个宏,而不管它们是否实际使用信号,槽和属性,因为它们不能执行 ,因此可能导致某些函数表现出奇怪的行为。

此类的构造函数需要公开Qt的内省设施才能够与类一起工作。