Qt/HTML交互库QtWeb+Cjax的实现

Qt与HTML通信在项目少量的使用还可以,大面积使用就比较麻烦,没有固定的模式接口。为了方便使用,封装了通信的库Qt端为QtWeb、HTML端为Cjax。

通信逻辑


QtWeb库

1、QtWeb库主要实现内容及功能:

  • 提供WebView用于加载显示Html页面
  • Html请求信号。收到前端请求后发出请求信号,信号中带有请求数据
  • 请求超时处理。前端发送的请求,上层为及时处理回复则进行超时处理
  • 主动推送消息到Html。提供notify接口,可主动推送消息到前端Html界面中
  • 通信协议采用json格式。

2、QtWeb库的具体实现

QtWeb.h头文件

#ifndef QTWEB_H
#define QTWEB_H

#include <QWebView>
#include "json/json.h"
using namespace std;

class QtWeb : public QWebView
{
	Q_OBJECT

public:
	QtWeb(QWidget *parent);
	~QtWeb();
	public slots:
		void dealLoadFinished(bool);
		void dealRequest(QString jsonStr);
		void registerJSObj();
		int responseInterFace(QString url, int state, QString data, QString dataType = "json");
		void webInterFace(QString url, QString dataType = "json", QString data = "");
		void checkTimeout();
public:
	void loadUrl(QString urlStr);

signals:
	void msgLoadFinish(bool);
	void msgSendRequest(QString, QString, QString);
	void msgRecieveJsonError(int); //参数为请求的错误码
private:
	QList<Json::Value> m_requestList;
};

#endif // QTWEB_H

QtWeb.cpp源文件

#include "qtweb.h"
#include <QWebPage>
#include <QWebFrame>
#include <QDate>
#include <qtimer.h>

QtWeb::QtWeb(QWidget *parent)
	: QWebView(parent)
{
	QTimer *checkTimer = new QTimer(this);
	connect(checkTimer, SIGNAL(timeout()), this, SLOT(checkTimeout()));
	checkTimer->start(1000);
	connect(this, SIGNAL(loadFinished(bool)), this, SLOT(dealLoadFinished(bool)));
	connect(page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(registerJSObj()));
	this->setStyleSheet(QString("QScrollBar::vertical{	background-color:rgb(54,80,79);margin:22px 0 22px 0;border:1px solid rgb(20,144,136);}\
								 QScrollBar::handle:vertical{	background-color:rgb(1,64,71);"));
}

QtWeb::~QtWeb()
{

}

//************************************
// Method:    registerJSObj
// FullName:  QtWeb::registerJSObj
// Access:    public 
// Returns:   void
// Func:      槽函数 注册Qt的对象以便HTML可以使用
//************************************
void QtWeb::registerJSObj()
{
	page()->mainFrame()->addToJavaScriptWindowObject(QString("QtWebObj"), this);
}

//************************************
// Method:    loadUrl
// FullName:  QtWeb::loadUrl
// Access:    public 
// Returns:   void
// Func:      对上层提供自己添加HTML的方法
// Parameter: QString urlStr  html所在路径
//************************************
void QtWeb::loadUrl(QString urlStr)
{
	this->load(QUrl(urlStr));
}

//************************************
// Method:    checkTimeout
// FullName:  QtWeb::checkTimeout
// Access:    public 
// Returns:   void
// Func:      定时器槽函数,定时检查请求是否处理超时,超时立即返回错误
//************************************
void QtWeb::checkTimeout()
{
	if (m_requestList.empty())
		return;
	foreach(Json::Value oneItem, m_requestList)
	{
		if ((oneItem["timestamp"].asInt() + oneItem["timeout"].asInt()/1000) < QDateTime::currentDateTime().toTime_t())
		{
			responseInterFace(QString::fromStdString(oneItem["url"].asString()), 504, "error", "Text");
			m_requestList.removeOne(oneItem);
		}
	}
}

//************************************
// Method:    dealLoadFinished
// FullName:  QtWeb::dealLoadFinished
// Access:    public 
// Returns:   void
// Func:      加载html的槽函数,触发信号,上层可根据参数bSuccess判断加载HTML是否成功
// Parameter: bool bSuccess 代表加载html是否成功
//************************************
void QtWeb::dealLoadFinished(bool bSuccess)
{
	emit msgLoadFinish(bSuccess);
}

//************************************
// Method:    dealRequest
// FullName:  QtWeb::dealRequest
// Access:    public 
// Returns:   void
// Func:      处理JS端的请求,发出信号,由上层处理,不是对Qt端提供的接口。
// Parameter: QString jsonStr JS端传来的请求格式是json字符串
//************************************
void QtWeb::dealRequest(QString jsonStr)
{
	Json::Reader reader;
	Json::Value root;
	if(reader.parse(jsonStr.toStdString().c_str(), root))
	{  不   
		root["timestamp"] = QDateTime::currentDateTime().toTime_t();
		m_requestList.append(root);
		string url = root["url"].asString();
		string type = root["type"].asString();
		string data = root["data"].asString();
		emit msgSendRequest(QString::fromStdString(url), QString::fromStdString(data), QString::fromStdString(type));
	}
	else
		emit msgRecieveJsonError(400);
}

//************************************
// Method:    responseInterFace
// FullName:  QtWeb::responseInterFace
// Access:    public 
// Returns:   int  0代表响应请求成功 -1代表失败
// Func:      响应JS请求,将上层获取的数据传回HTML
// Parameter: QString url				指令
// Parameter: int state					状态码
// Parameter: QString data				返回数据
// Parameter: QString dataType			数据类型
//************************************
int QtWeb::responseInterFace(QString url, int state, QString data, QString dataType /* = "json" */)
{
	int countNum = 0;
	foreach(Json::Value oneItem, m_requestList)
	{
		if (QString::fromStdString(oneItem["url"].asString()) == url)
		{
			Json::Value item;
			item["url"] = url.toStdString();
			item["state"] = state;
			item["datatype"] = dataType.toStdString();
			item["data"] = data.toStdString();
			string jsonStr = item.toStyledString();
			page()->mainFrame()->evaluateJavaScript(QString("responseInterFace(%1)").arg(QString::fromLocal8Bit(jsonStr.c_str())));
			m_requestList.removeOne(oneItem);
			break;
		}
		else
			countNum++;
	}
	if (countNum == m_requestList.length())
		return -1;
	return 0;
}

//************************************
// Method:    webInterFace
// FullName:  QtWeb::webInterFace
// Access:    public 
// Returns:   void
// Func:      Qt端主动推送信号或数据的接口
// Parameter: QString url			指令
// Parameter: QString dataType		数据类型
// Parameter: QString data			推送的数据
//************************************
void QtWeb::webInterFace(QString url, QString dataType /* = "json" */, QString data /* = "" */)
{
	Json::Value item;
	item["url"] = url.toStdString();
	item["datatype"] = dataType.toStdString();
	item["data"] = data.toStdString();
	string jsonStr = item.toStyledString();
	page()->mainFrame()->evaluateJavaScript(QString("webInterFace(%1)").arg(QString::fromLocal8Bit(jsonStr.c_str())));
}

HTML端CJAX的具体实现

在前端开发中与后台通信时经常会使用到AJax,Html与Qt的通信也模仿AJax的使用方法和逻辑实现了CJax,意为与C++的通信。显示的逻辑中主要用到了回调函数,向Qt端发送请求后的success函数和error函数都是采用回调函数实现,还有Qt端主动发送的Notify消息也是预先注册好回调函数进行处理。

1、CJax主要功能:

  • 支持GET\POST\GO三个协议类型
  • 对请求协议格式进行了封装。模仿AJax的格式进行封装,数据支持json\text\xml
  • Notify消息预先注册,消息回调。

2、CJax插件的具体实现

cjax.js

/*****************************************************
 *插件名称:CJAX
 *创建时间:2016年11月04日
 *创 建 人:EdwardYang
 *插件功能描述:
 *		提供Qt程序加载html界面显示时,html界面和Qt程序的交互功能
 *		html--->Qt  提供:
 *
 *********************************************************/
 
 //保存所有未完成的请求数据对象
var requestBobyList = [];
 
 //用于保存notify指令与回调函数的对应
var notifyCMDObjects= [];
 
 /***************************************
  *方法名称:CJax
  *参    数  requestBody  请求数据对象
  *功能描述:向Qt端发送request请求
  requestBody对象格式:
		{
			url:"",			//请求指令
			type:"",		//请求方式(Get、POST、GO)
			timeout:3000,	//请求超时时间
			async:true,	//请求回应方式
			data:"",		//请求数据,之后在POST的时候使用。数据为Json格式的字符串
			success:,		//请求成功后回调函数,函数原型function(data){}
			error:,			//请求失败时被调用的函数,函数原型function(errNo){}
		}
		
向Qt发送请求json格式
		{
		
		}
  **************************************/
var cjax = function(requestBody)
{
	 //将请求添加到请求列表中
	requestBobyList.push(requestBody);
	var paramObj = {};
	paramObj.url = requestBody.url;
	paramObj.type = requestBody.type;
	paramObj.timeout = requestBody.timeout;
	paramObj.data = requestBody.data;
	var str = JSON.stringify(paramObj);
	QtWebObj.dealRequest(str);
}
 
 /*********************************************************
  *方法名称:responseInterFace
  *参    数:responseBody  请求返回数据 json格式
  *功能说明:发送请求之后,Qt端返回的数据
		  {
			  "url":"",					//请求指令
			  "state":200,					//请求返回值
			  "datatype":"xml/json/text",	//返回数据类型
			  "data":""						//返回数据
		  }
  *********************************************************/
var responseInterFace = function(responseBody)
{
	var url = responseBody.url;
	for (var i = 0; i < requestBobyList.length; i++)
	{
		if(requestBobyList[i].url == url)
		{
			var callback;
			if (responseBody.state != 200)
				callback = requestBobyList[i].error;
			else
				callback = requestBobyList[i].success;
			callback.call(this, responseBody.datatype, responseBody.data);
			requestBobyList.splice(i, 1);
			break;
		}
	}
}
  
 /*********************************************************
  *方法名称:webInterFace
  *参    数:notifyObj Qt端推送过来的信息结构对象  	callback指令对应的毁掉函数
  *功能说明:Qt端主动推送消息通知接口
		{
			"url":"指令",					//消息指令
			"datatype":"xml/json/text",	//数据类型
			"data":""						//数据
		}
  ***********************************************************/
var webInterFace = function(notifyObj)
{
	var url = notifyObj.url;
	for (var i = 0; i < notifyCMDObjects.length; i++)
	{
		if(notifyCMDObjects[i].notifyCmd == url)
		{
			var callback = notifyCMDObjects[i].func;
			callback.call(this, notifyObj.datatype, notifyObj.data);
			break;
		}
	}
}
  
  /*********************************************************
  *方法名称:insertNotifyCMDCallBack
  *参    数:cmd 指令  callback 回调函数
  *功能说明:保存所有QT端推送的指令和其对应的回调函数
  ***********************************************************/
var insertNotifyCMDCallBack = function(cmd,  callback)
{
	var cmdObject = {
		notifyCmd:cmd,
		func:callback
	}
	notifyCMDObjects.push(cmdObject);
}
  


  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值