久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

實現(xiàn)QT與HTML頁面通信

 LZS2851 2016-04-05

1.  前言

最近,,C++和WEB本地混合應(yīng)用開發(fā)模式逐漸流行起來,個人也認為標記語言描述的界面是界面開發(fā)的一個發(fā)展趨勢,。WPF,、Java FX,當然也少不了Html,?;贖tml的界面在開發(fā)效率,可移植性上都十分有優(yōu)勢,,所以也被很多程序采用

隨著HTML5技術(shù)風生水起,,Qt開發(fā)團隊用近一年的時間開發(fā)了一個全新的基于Chromium的瀏覽器引擎Qt WebEngine,以支持面向未來的Hybrid應(yīng)用開發(fā),,并完全支持桌面和嵌入式平臺,。此外,Qt WebEngine不僅提供了易于使用的跨平臺API,,還完全集成了Qt的圖形庫,,允許網(wǎng)頁內(nèi)容進行疊加,并與Qt用戶界面或OpenGL圖形效果混合,。Qt 5.4仍然包含老舊的Qt WebKit模塊,,但在其后發(fā)布的版本中將停止對于WebKit的支持,對此,,Qt團隊建議開發(fā)者將項目統(tǒng)一從WebKit遷移至Qt WebEngine,,而對于需要Web能力的新項目,最好直接采用Qt WebEngine開發(fā),。在現(xiàn)在下載的QT5.6 beta預(yù)編譯版本中已經(jīng)沒有了Qt WebKit模塊,。


目前QT官方的文檔中對如何從原來的WebKit遷移至QtWebEngine沒有提供足夠豐富的文檔和指導(dǎo)。

本文記錄一些從WebKit遷移至QtWebEngine,,實現(xiàn)C++與HTML和JS交互的一些經(jīng)驗和例子,。

2.  使用Qt WebEngine和WebChannel模塊

在官方提供的Porting from QtWebKit to QtWebEngine---https://wiki./Porting_from_QtWebKit_to_QtWebEngine文檔中給出了從WebKit遷移至QtWebEngine的一些建議和指導(dǎo),其中提到QWebFrame 已經(jīng)被合并到QwebEnginePage中,,Qt WebEngine不能和QnetworkAccessManager交互等,。

原來在Webkit中使用的交互集成的類和方法也不能使用了,原來Webkit中常用的交互方式如下:

1)    Qt代碼中加載并顯示該頁面

QWebView view; 

view.load(QUrl("test.html")); 

view.show();

 

官方推薦的使用方式:

 

QWebEngineView*view = newQWebEngineView(parent);

    view->load(QUrl("http:///"));

   view->show();

 

2)    Qt對象中訪問web頁面元素

// myPlugin指向的對象可在HTML中用名字myPluginObject進行訪問 

webView->page()->mainFrame()->addToJavaScriptWindowObject("myPluginObject",myPlugin); 

// 當信號signalEmitted被觸發(fā)時,調(diào)用JavaScriptfunctionToCall函數(shù) 

webView->page()->mainFrame()->evaluateJavaScript("myPluginObject.signalEmitted.connect(functionToCall);")

 

官方推薦的使用方式:

方法一:QWebEnginePagerunJavaScript(const QString & scriptSource, FunctorOrLambdaresultCallback)

方法二:使用QtWebChannel方式,,這是官方的推薦方式,,他可以很方便的實現(xiàn)C++和HTML/JS的雙向通信,同時實現(xiàn)C++和HTML/JS的解耦,,方便開發(fā)人員的分工及系統(tǒng)集成,,參見后面的例子。

3)    web頁面中訪問Qt對象

web頁面中可以通過類似于下的JavaScript代碼訪問Qt對象:

<ahref="javascript:document.getElementByIdx_x("myLabel").setText("通過JavaScript訪問Qt對象");"mce_href="javascript:document.getElementByIdx_x("myLabel").setText("通過JavaScript訪問Qt對象");">點擊訪問Qt對象</a>

 

官方推薦的使用方式:

使用QtWebChannel方式,,這是官方的推薦方式,,他可以很方便的實現(xiàn)C++和HTML/JS的雙向通信,同時實現(xiàn)C++和HTML/JS的解耦,,方便開發(fā)人員的分工及系統(tǒng)集成,,參見后面的例子。

在QT5.5和QT5.6中,,利用Qt的Qt WebEngine和WebChannel模塊,,你完全可以進行本地桌面與web混合應(yīng)用開發(fā),你可以自由地混合JavaScript,,樣式表,Web內(nèi)容和Qt組件,?;?a target="_blank" href="http://www./">Chromium的 Qt WebEngine是一個非常成熟的web瀏覽引擎。你可以在C++ 中執(zhí)行JavaScript,,或者在網(wǎng)頁中集成C++對象,,并且通過JavaScript和這些對象進行交互。

一個現(xiàn)代的HTML渲染引擎只是混合開發(fā)的一半,,另一半就是本地應(yīng)用和渲染對象的交互,。QT的Chromium Qt WebEngine 集成提供了這種解決方案,當然目前還不是很完善,。

從QT5.4開始就新增了Qt WebChannel模塊,,該模塊提供了在QML/C++ 和 HTML/Javascript之間的一個簡單、易用的橋接,,從而使得開發(fā)能夠使用Qt和Web技術(shù)進行混合開發(fā),,目前QT官方也推薦是用QtWebChannel來橋接C++和HTML,參見Qt WebChannel – bridging the gap betweenC++/QML and the web------https://www./watch?v=KnvnTi6XafA,,這是2014年Qt開發(fā)者大會上的一段視屏演講,。

通過QtWebChannel能夠?qū)崿F(xiàn)C++/QML和HTML/javascript客戶端之間進行無縫橋接,目前主要支持兩種方式的橋接,。

  • l  客戶機可以是任何支持WebSockets的JavaScript runtime機器和應(yīng)用,,客戶機可以是獨立的應(yīng)用或瀏覽器。也就是說QtWebChannel是基于WebSockets協(xié)議之上。
  • l  通過IPC的方式實現(xiàn)C++/QML和HTML/javascript客戶端之間進行通信,。在QT應(yīng)用內(nèi)嵌入HTML或JS頁面的情況下使用基于IPC的WebChannel通信效率更高效,。

 

在官方演進路線中提到將來的集成解決方案將支持以下特性:

  • l  使用object標簽嵌入Qt Widgets組件。這可以讓使用C++代碼的Qt組件包含在網(wǎng)頁中,,作為網(wǎng)頁的部分外觀,。
  • l  在JavaScript中訪問C++對象。你可以在JavaScript環(huán)境中插入C++對象,,讓網(wǎng)頁腳本直接訪問你的數(shù)據(jù)結(jié)構(gòu),。
  • l  在Qt中執(zhí)行JavaScript。你可以在C++調(diào)用網(wǎng)頁環(huán)境中的JavaScript函數(shù),,觸發(fā)網(wǎng)頁事件,。
  • l  共享客戶端存儲。在JavaScript和C++中你都具有訪問數(shù)據(jù)庫的能力,,這樣當下線時也能共享大量數(shù)據(jù),。

 

3.  QtWebChannel實現(xiàn)C++和HTML/javascript頁面之間通信實例

在實例中在一個界面里實現(xiàn)集成QT C++組件和QWebEnginePage中嵌入的HTML頁面通信,左邊的lineedit組件中輸入的內(nèi)容通過一個document對象又QtWebChannel傳到web頁面,,并又js解析在HTML頁面上顯示,,右邊HTML頁面中的INPUT標簽中輸入的內(nèi)容也由document對象通過QtWebChannel傳到QT C++界面。通過QtWebChannel使得JS能夠接收到QT C++中傳出的對象,,及由C++發(fā)出的信號,,并與相對應(yīng)的方法關(guān)聯(lián),C++也能介紹到由JS傳來的對象,,并調(diào)用相應(yīng)的槽函數(shù),。

 

工程清單如下:


首先,定義一個document對象用于在C++和JS之間傳遞,,該對象實現(xiàn)了信號和槽:

 

Document.h內(nèi)容:

 

#ifndefDOCUMENT_H
#defineDOCUMENT_H
 
#include<QObject>
#include<QString>
#include"ui_mainwidget.h"
 
namespaceUi{
classMainWidget;
}
 
classDocument:publicQObject
{
    Q_OBJECT
    Q_PROPERTY(QStringtextMEMBERs_textNOTIFYsendText)
 
public:
    explicitDocument(QObject*parent=nullptr):QObject(parent){}
 
    voidsetSendTextText(constQString&text);
    voidsetUi(Ui::MainWidget*ui);
 
publicslots:
    voidreceiveText(constQString&r_text);
 
signals:
    voidsendText(constQString&text);
 
private:
    voiddisplayMessage(constQString&message);
    QStrings_text;
    QStringrecieve_text;
    Ui::MainWidget*mainUi;
};
 
#endif//DOCUMENT_H

 

Document.cpp內(nèi)容:

 

#include"document.h"
 
voidDocument::setSendTextText(constQString&text)
{
    s_text=text;
    emitsendText(s_text);
}
 
voidDocument::displayMessage(constQString&message)
{
      mainUi->editor->appendPlainText(message);
}
 
/*!
    ThisslotisinvokedfromtheHTMLclientsideandthetextdisplayedontheserverside.
*/
voidDocument::receiveText(constQString&r_text)
{
    displayMessage(QObject::tr("Receivedmessage:%1").arg(r_text));
}
 
voidDocument::setUi(Ui::MainWidget*ui)
{
    mainUi=ui;

}

 

用QT Designer設(shè)計主界面,,并實現(xiàn)主界面MainWidget類,內(nèi)容如下:

 

mainwidget.h內(nèi)容:

 

#ifndefMAINWIDGET_H
#defineMAINWIDGET_H
 
#include"document.h"
 
#include<QWidget>
#include<QString>
 
namespaceUi{
classMainWidget;
}
 
classMainWidget:publicQWidget
{
    Q_OBJECT
 
public:
    explicitMainWidget(QWidget*parent=0);
    ~MainWidget();
 
//publicQ_SLOTS:
//    voidsetEnabled(bool);
 
privateslots:
    voidon_pushButton_clicked();
 
private:
    boolisModified()const;
 
    Ui::MainWidget*ui;
    Documentm_content;
 
};
 
#endif//MAINWIDGET_H

 

mainwidget.cpp內(nèi)容:

 

#include"mainwidget.h"
#include"ui_mainwidget.h"
#include"previewpage.h"
#include"document.h"
 
#include<QFile>
#include<QWebChannel>
 
MainWidget::MainWidget(QWidget*parent):
    QWidget(parent),
    ui(newUi::MainWidget)
{
    ui->setupUi(this);
 
    PreviewPage*page=newPreviewPage(this);
    ui->preview->setPage(page);
    m_content.setUi(ui);
 
    QWebChannel*channel=newQWebChannel(this);
    channel->registerObject(QStringLiteral("content"),&m_content);
    page->setWebChannel(channel);
 
    ui->preview->setUrl(QUrl("qrc:/index.html"));
 
    ui->editor->setPlainText("hello...\n");
}
 
MainWidget::~MainWidget()
{
    deleteui;
}
 
boolMainWidget::isModified()const
{
    returnui->editor->document()->isModified();
}
 
voidMainWidget::on_pushButton_clicked()
{
 
    m_content.setSendTextText(ui->lineEdit->text());
 
}

 

再定義一個PreviewPage類用于加載HTML頁面,,在主界面MainWidget類初始化的時候,,將他主界面中的WebEngineView初始化為該實例對象,主要初始化代碼如下:

PreviewPage*page=newPreviewPage(this);  //創(chuàng)建實例對象

    ui->preview->setPage(page);                 //將對象設(shè)置到主界面

ui->preview->setUrl(QUrl("qrc:/index.html"));                               //設(shè)置載入的HTML頁面

 

previewpage.h內(nèi)容:

 

#ifndefPREVIEWPAGE_H
#definePREVIEWPAGE_H
 
#include<QWebEnginePage>
 
classPreviewPage:publicQWebEnginePage
{
    Q_OBJECT
public:
    explicitPreviewPage(QObject*parent=nullptr):QWebEnginePage(parent){}
 
protected:
    boolacceptNavigationRequest(constQUrl&url,NavigationTypetype,boolisMainFrame);
};
 
#endif//PREVIEWPAGE_H

 

previewpage.cpp內(nèi)容:

 

#include"previewpage.h"

 

#include<QDesktopServices>

 

boolPreviewPage::acceptNavigationRequest(constQUrl&url,

                                         QWebEnginePage::NavigationType/*type*/,

                                         bool/*isMainFrame*/)

{

    //Onlyallowqrc:/index.html.

    if(url.scheme()==QString("qrc"))

       returntrue;

    QDesktopServices::openUrl(url);

    returnfalse;

}

 

使用的web頁面index.html內(nèi)容如下:

 

<!DOCTYPEhtml>

<html>

    <head>

       <metahttp-equiv="Content-Type"content="text/html;charset=utf-8"/>

       <scripttype="text/javascript"src="./qwebchannel.js"></script>

       <scripttype="text/javascript">

           //BEGINSETUP

           functionoutput(message)

           {

                varoutput=document.getElementById("output");

                output.innerHTML=output.innerHTML+message+"\n";

           }

           window.onload=function(){

 

           output("settingupQWebChannel.");

           newQWebChannel(qt.webChannelTransport,function(channel){

                //makedialogobjectaccessibleglobally

                varcontent=channel.objects.content;

 

                document.getElementById("send").onclick=function(){

                    varinput=document.getElementById("input");

                    vartext=input.value;

                    if(!text){

                        return;

                    }

 

                    output("Sentmessage:"+text);

                    input.value="";

                    content.receiveText(text);

                }

 

                content.sendText.connect(function(message){

                    output("Receivedmessage:"+message);

                });

 

                content.receiveText("Clientconnected,readytosend/receivemessages!");

                output("ConnectedtoWebChannel,readytosend/receivemessages!");

           });

           }

 

           //ENDSETUP

       </script>

       <styletype="text/css">

           html{

                height:100%;

                width:100%;

           }

           #input{

                width:400px;

                margin:010px00;

           }

           #send{

                width:90px;

                margin:0;

           }

           #output{

                width:500px;

                height:300px;

           }

       </style>

    </head>

    <body>

       <textareaid="output"></textarea><br/>

       <inputid="input"/><inputtype="submit"id="send"value="Send"onclick="javascript:click();"/>

    </body>

</html>

 

主程序main.cpp的內(nèi)容如下:

 

#include"document.h"

#include"mainwidget.h"

#include<QApplication>

 

intmain(intargc,char*argv[])

{

    QApplicationa(argc,argv);

    MainWidgetw;

    w.show();

 

    returna.exec();

}

文中使用的例子可以到鏈接:http://download.csdn.net/detail/liuyez123/9402132地址下載,。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多