您的位置:首页 > 编程语言 > Qt开发

实现QT与HTML页面通信

2016-06-26 12:36 246 查看

1.前言

最近,C++和WEB本地混合应用开发模式逐渐流行起来,个人也认为标记语言描述的界面是界面开发的一个发展趋势。WPF、JavaFX,当然也少不了Html。基于Html的界面在开发效率,可移植性上都十分有优势,所以也被很多

目前QT官方的文档中对如何从原来的WebKit迁移至QtWebEngine没有提供足够丰富的文档和指导。

本文记录一些从WebKit迁移至QtWebEngine,实现C++与HTML和JS交互的一些经验和例子。

2.使用QtWebEngine和WebChannel模块

在官方提供的PortingfromQtWebKittoQtWebEngine---QWebEngineView*view=newQUrl("http://qt-project.org/"));

view->show();

2)在Qt对象中访问web页面元素

//myPlugin指向的对象可在HTML中用名字myPluginObject进行访问

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

//当信号signalEmitted被触发时,调用JavaScript的functionToCall函数

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

官方推荐的使用方式:

方法一:runJavaScript(const

QString&scriptSource,FunctorOrLambdaresultCallback)

方法二:使用QtWebChannel方式,这是官方的推荐方式,他可以很方便的实现C++和HTML/JS的双向通信,同时实现C++和HTML/JS的解耦,方便开发人员的分工及系统集成,参见后面的例子。

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方式,这是官方的推荐方式,他可以很方便的实现C++和HTML/JS的双向通信,同时实现C++和HTML/JS的解耦,方便开发人员的分工及系统集成,参见后面的例子。

在QT5.5和QT5.6中,利用Qt的QtWebEngine和WebChannel模块,你完全可以进行本地桌面与web混合应用开发,你可以自由地混合JavaScript,样式表,Web内容和Qt组件。基于Chromium的QtWebChannel模块,该模块提供了在QML/C++和HTML/Javascript之间的一个简单、易用的桥接,从而使得开发能够使用Qt和Web技术进行混合开发,目前QT官方也推荐是用QtWebChannel来桥接C++和HTML,参见Qt

WebChannel–bridgingthegapbetweenC++/QMLandtheweb------

首先,定义一个document对象用于在C++和JS之间传递,该对象实现了信号和槽:

Document.h内容:

#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内容:

#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;


}

用QTDesigner设计主界面,并实现主界面MainWidget类,内容如下:

mainwidget.h内容:

#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内容:

#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);//创建实例对象

ui->preview->setPage(page);//将对象设置到主界面

ui->preview->setUrl(QUrl("qrc:/index.html"));//设置载入的HTML页面

previewpage.h内容:

#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内容:

#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内容如下:

<!DOCTYPE
html>

<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的内容如下:

#include"document.h"

#include"mainwidget.h"

#include<QApplication>

intmain(intargc,char*argv[])

{

QApplicationa(argc,argv);

MainWidgetw;

w.show();

returna.exec();

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: