QCefView应用和网页的交互

一、demo的主要项目文件

结合QCefView自带的demo代码

main.cpp

#include

#include <QCefContext.h>

#include "MainWindow.h"

int

main(int argc, char* argv\[\])

{

QApplication a(argc, argv);

// build QCefConfig

QCefConfig config;

config.setUserAgent("QCefViewTest");

config.setLogLevel(QCefConfig::LOGSEVERITY_DEFAULT);

///桥对象表示一个Javascript对象,它将被插入

///进入所有的浏览器和框架。该对象被指定用于通信

///在web内容中的Javascript和本地上下文(C/ c++)代码之间。

///该对象被设置为window对象的属性。这意味着它可以

///通过调用window获取。Javascript代码中的bridgeObject

config.setBridgeObjectName("QCefClient");//这个很关键

config.setRemoteDebuggingPort(9000);

config.setBackgroundColor(Qt::lightGray);

// WindowlessRenderingEnabled is set to true by default, set to false to disable the OSR mode

// config.setWindowlessRenderingEnabled(false);

// add command line args

config.addCommandLineSwitch("use-mock-keychain");

// config.addCommandLineSwitch("disable-gpu");

// config.addCommandLineSwitch("enable-media-stream");

// config.addCommandLineSwitch("allow-file-access-from-files");

// config.addCommandLineSwitch("disable-spell-checking");

// config.addCommandLineSwitch("disable-site-isolation-trials");

// config.addCommandLineSwitch("enable-aggressive-domstorage-flushing");

config.addCommandLineSwitchWithValue("renderer-process-limit", "1");

config.setCachePath(QCoreApplication::applicationDirPath());

// config.addCommandLineSwitchWithValue("disable-features", "BlinkGenPropertyTrees,TranslateUI,site-per-process");

// initialize QCefContext instance with config

QCefContext cefContext(&a, argc, argv, &config);

MainWindow w;

w.show();

return a.exec();

}

customcefview.h

#ifndef CUSTOMCEFVIEW_H

#define CUSTOMCEFVIEW_H

#include <include/QCefView.h>

#include "configurationTool/configuration.h"

#include "MessageDistribution.h"

class CustomCefView : public QCefView

{

Q_OBJECT

public:

CustomCefView(const QString& url, QWidget *parent);

~CustomCefView();

复制代码
/*通过事件注册的方式,将消息发送给JS*/
void changeColor(); // 背景颜色发生改变
void languageChange(QString language); // 语言发生改变的槽函数

/接收JS端发送给Qt的消息 /

protected slots:

virtual void onQCefUrlRequest(const QString& url) override;

virtual void onQCefQueryRequest(const QCefQuery& query) override;

virtual void onInvokeMethodNotify(int browserId, int frameId, const QString& method, const QVariantList& arguments) override;

void onLoadingStateChanged(bool isLoading, bool canGoBack, bool canGoForward) override;

void onLoadStart() override;

void onLoadEnd(int httpStatusCode) override;

void onLoadError(int errorCode, const QString &errorMsg, const QString &failedUrl) override;

private:

Configuration configuration; // 通讯配置工具

MessageDistributionHandle msgHandle;// 消息分发处理

};

#endif // CUSTOMCEFVIEW_H

对应的customcefview.cpp 中,我们来看如何实现事件注册,以及接收到JS消息后,Qt如何处理的:

#include <windows.h>

#include

#include

#include "customcefview.h"
:
QCefView(url, parent)

复制代码
{   

}

CustomCefView::~CustomCefView() {}

/// 注册一个窗体颜色改变的事件==》Qt发送消息到网页端,网页端接受该事件消息后响应

void CustomCefView::changeColor()

{

qsrand(::GetTickCount());

QColor color(qrand());

//
QCefEvent event("colorChangedEvent");
event.setStringProperty("color", color.name()); // 定义事件属性参数
broadcastEvent("colorChange", event); // 广播事件
/
/

}

注册一个语言槽函数

void CustomCefView::languageChange(QString language) {

QCefEvent event("languageChangedEvent");

event.setStringProperty("language", language);

broadcastEvent("languageChange", event);

}

void CustomCefView::onQCefUrlRequest(const QString& url)

{

QString title("QCef Url Request ...function onQCefUrlRequest");

QString text = QString("Current Thread: QT_UI\r\n"

"Url: %1")

.arg(url);

QMessageBox::information(this->window(), title, text);

}

/// 接收由JS发送过来的消息并回包

void CustomCefView::onQCefQueryRequest(const QCefQuery& query)

{

QString title("QCef Query Request");

QString text = QString("Current Thread: QT_UI\r\n"

"Query: %1")

.arg(query.reqeust());

QMessageBox::information(this->window(), title, text);

QString response = query.reqeust().toUpper();

query.setResponseResult(true, response);

responseQCefQuery(query);

}

/// 接受由JS发送的消息

void CustomCefView::onInvokeMethodNotify(int browserId, int frameId, const QString& method, const QVariantList& arguments)

{

/** 注意:JS端通过调用 invokeMethod 方法,实际上会有两个参数变量传递过来,

** 一个是 const QString& method, 通过method我们可以进行消息过滤,在Qt中进行消息分发处理

** 另一个是const QVariantList& arguments,通过变量类型我们可知,这个参数同时可以传递多种

** 不同类型的数据到Qt中来,我们可以通过解析消息体,做具体的业务处理。

**/

qDebug() << "browserId:" << browserId << " frameId:" << frameId << " method:" << method << "arguments:" << arguments;

if (0 == method.compare("onDragAreaMouseDown")) { // for test

HWND hWnd = ::GetAncestor((HWND)getCefWinId(), GA_ROOT);

复制代码
// get current mouse cursor position
POINT pt;
::GetCursorPos(&pt);

// in case the mouse is being captured, try to release it
::ReleaseCapture();

// simulate that the mouse left button is down on the title area
::SendMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, POINTTOPOINTS(pt));
return;

}

else if (0 == method.compare("configurationTool")) { // 调用通讯配置工具

configuration.show();

}

else if (0 == method.compare("openLuaEditor")) { // 打开lua脚本编辑器

QString Luaparam(arguments.last().value());

msgHandle.luaScriptEditHandle(Luaparam);

}

else {

QString title("QCef InvokeMethod Notify");

QString text = QString("Current Thread: QT_UI\r\n"

"Method: %1\r\n"

"Arguments: ...")

.arg(method);

QMessageBox::information(this->window(), title, text);

}

}

void CustomCefView::onLoadingStateChanged(bool isLoading, bool canGoBack, bool canGoForward)

{

qDebug() << "isLoading:" << isLoading << "canGoBack" << canGoBack << "canGoForward" << canGoForward;

}

void CustomCefView::onLoadStart()

{

qDebug() << "onLoadStart";

}

void CustomCefView::onLoadEnd(int httpStatusCode)

{

qDebug() << "onLoadEnd" << httpStatusCode;

}

void CustomCefView::onLoadError(int errorCode, const QString &errorMsg, const QString &failedUrl)

{

qDebug() << "onLoadError" << errorCode << errorMsg << failedUrl;

}

二、QT与JS通讯

1、Qt发送消息给JS部分

void CustomCefView::changeColor()

{

qsrand(::GetTickCount());

QColor color(qrand());

/****************以注册消息事件的方式将消息从Qt发送到JS /

QCefEvent event("colorChangedEvent");

event.setStringProperty("color", color.name()); // 定义事件属性参数

broadcastEvent("colorChange", event); // 广播事件

/****************************************************************/

}

2、Qt接收JS消息部分

void CustomCefView::onInvokeMethodNotify(int browserId, int frameId, const QString& method, const QVariantList& arguments)

{

/** 注意:JS端通过调用 invokeMethod 方法,实际上会有两个参数变量传递过来,

** 一个是 const QString& method, 通过method我们可以进行消息过滤,在Qt中进行消息分发处理

** 另一个是const QVariantList& arguments,通过变量类型我们可知,这个参数同时可以传递多种

** 不同类型的数据到Qt中来,我们可以通过解析消息体,做具体的业务处理。

**/

qDebug() << "browserId:" << browserId << " frameId:" << frameId << " method:" << method << "arguments:" << arguments;

if (0 == method.compare("onDragAreaMouseDown")) { // for test

HWND hWnd = ::GetAncestor((HWND)getCefWinId(), GA_ROOT);

复制代码
// get current mouse cursor position
POINT pt;
::GetCursorPos(&pt);

// in case the mouse is being captured, try to release it
::ReleaseCapture();

// simulate that the mouse left button is down on the title area
::SendMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, POINTTOPOINTS(pt));
return;

}

else if (0 == method.compare("configurationTool")) { // 调用通讯配置工具

configuration.show();

}

else if (0 == method.compare("openLuaEditor")) { // 打开lua脚本编辑器

QString Luaparam(arguments.last().value());

msgHandle.luaScriptEditHandle(Luaparam);

}

else {

QString title("QCef InvokeMethod Notify");

QString text = QString("Current Thread: QT_UI\r\n"

"Method: %1\r\n"

"Arguments: ...")

.arg(method);

QMessageBox::information(this->window(), title, text);

}

}

3、html中如何处理Qt与JS通讯部分具体的消息收发的

Web Area

Test Case for InvokeMethod

Test Case for QCefQuery
this message will be processed by native code.

Test Case for QCefUrlQuery
百度

Open Popup
{"data" : { "rows" : { "flag_addr_label_id" : "0","font_size" : 11,"id" : 0,"name" : "test","save_bit_address_flag" : 0, "text" :"getHmiModel()","trigger_addr_label_ids" :"","trigger_addr_labels" : "","trigger_type" : 0,"type" : 1,"var_list" : ""}}}"
4、JS接收Qt消息部分

function onLoad() {

if (typeof (QCefClient) == 'undefined') {

return;

}

复制代码
       // 增加颜色改变事件的监听
       QCefClient.addEventListener("colorChange", onColorChanged);
       QCefClient.addEventListener("languageChange", onLanguageChanged);
   }

在onLoad() 方法中实际上是做了一个事件监听的,对应我们在Qt端注册的 "colorChange" 和"languageChange",当Qt端调用changeColor ()和languageChange()方法时,会触发对应的事件,JS端捕获该事件并做处理,实际上就是实现了Qt(发)==》JS(收)的一个通讯过程。

5、JS发送消息给Qt:

function onOpenConfigurationTool() {

QCefClient.invokeMethod("configurationTool", 1, false, "configurationTool");

}

从上可以看到,在调用invokeMethod()方法时候,传递了4个参数,分别是:

method : string "configurationTool"

arguments: int 1

bool false

string "configurationTool"

结合我们在Qt讲到的接收JS消息和对应处理,一目了然了。

相关推荐
用户805533698032 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner2 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz7 天前
QML Hello World 入门示例
qt
xcyxiner10 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner11 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner11 天前
DicomViewer (添加模型类)3
qt
xcyxiner12 天前
DicomViewer (目录调整) 2
qt
xcyxiner12 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
桥田智能14 天前
桥田智能 QT-650S:面向白车身焊装的 800kg 重载快换解决方案
开发语言·qt·系统架构
北极星日淘14 天前
前端 i18n 中日双语交互 + 翻译客服接口联动方案|日系海淘平台中文友好化开发实战
前端·交互