2017-08-10 72 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的內省設施才能夠與類一起工作。