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消息和对应处理,一目了然了。

相关推荐
慧都小项4 天前
当边缘AI上产线:QtitanDocking 如何让工业 HMI 实现多视图协同
人工智能·qt·ui·边缘计算·qt6.3
Quz4 天前
QML SwipeDelegate 滑动委托
qt
Quz4 天前
QML 列表中的四种委托:ItemDelegate、CheckDelegate、RadioDelegate、SwitchDelegate
qt
实心儿儿4 天前
Qt — 显示类控件
qt
元岳数字人小元4 天前
无惧网络受限:数字人私有化部署打造离线全域服务能力
运维·人工智能·开源·人机交互·交互
兰亭妙微UI设计公司5 天前
兰亭妙微UI设计公司分享:EQUA 智能健康生态系统 UI/UX 设计深度解析
ui·交互
江湖人称菠萝包5 天前
【Qt】《Qt 5.9 C++开发指南》笔记-Chapter9-Qt Charts
笔记·qt·qt5
扶尔魔ocy5 天前
【QT android】环境安装及第一个QT项目
qt·andriod开发
江湖人称菠萝包5 天前
【Qt】《Qt 5.9 C++开发指南》笔记-Chapter10-Data Visualization
笔记·qt·qt5
Cx330❀5 天前
Qt 常用控件属性与底层机制详解:从窗口半透明、浮点数陷阱到 QSS 与焦点策略
qt·ui·图形渲染