精华内容
下载资源
问答
  • qt与js交互

    2017-11-01 18:05:51
    本文使用开发环境是VS2015+Qt5.9,然后安装qt-vs-addin-1.2.5.exe插件。使用到的Qt5WebEngine作为网页加载显示,然后用QtWebChannel作为Qt与Javascript交互通讯的桥梁,这也是官方推荐的方法。
  • Qt与JS的数据交互

    2018-04-19 15:11:34
    演示了使用 QWebChannel 在Qt(QWebEngineView/QWebEnginePage)与JS之间的数据交互。示例工程非常简单,使用QtCreator直接打开即可运行(需Qt5.6.2以上)。
  • QT与JS互调实例

    热门讨论 2012-05-29 21:39:09
    QT与JavaScript互调是通过QWebFrame的两个函数来实现的:addToJavaScriptWindowObject()将QObject对象传给JS,这样JS就能调用QObject的public slots函数。QT通过evaluateJavaScript()直接调用JS中的函数
  • Qt与JS通讯 1、Qt发送消息给JS部分: 2、Qt接收JS消息部分: 3、JS接收Qt消息部分: 4、JS发送消息给Qt: 程序运行效果图: 前言 在上一篇(QCefView(1)—— CMAKE项目、库文件生成和项目测试)同大家...

    目录

     

    前言   

    主要项目文件

    Qt与JS通讯

    1、Qt发送消息给JS部分:

    2、Qt接收JS消息部分:

    3、JS接收Qt消息部分:

    4、JS发送消息给Qt:

    程序运行效果图:


    前言   

       在上一篇(QCefView(1)—— CMAKE项目、库文件生成和项目测试)同大家一起分享了QCefView的编译环境搭建、库文件编译,和测试项目运行等,本章,主要和大家分享和研究下基于QCefView实现的Qt与JS通讯的部分。

    主要项目文件

    在测试项目中我们看到 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 <QMessageBox>
    #include <QColor>
    #include "customcefview.h"
    
    
    CustomCefView::CustomCefView(const QString& url, QWidget* parent)
      : 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<QString>());
    	  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消息部分:

    从上面代码中可以看到,实际上有三种接收的方式,这里我们同样只关注因为invokeMethod()方法JS发送给Qt的消息处理

    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<QString>());
    	  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);
      }
    }

     

    对照我们看看在html中如何处理Qt与JS通讯部分具体的消息收发的:

    <html>
    <head>
        <script>
            // 捕获Qt发送给JS事件信号的函数
            function onColorChanged(event) {
                document.getElementById("main").style.backgroundColor = event["color"];
                alert(event["color"]);
            }
    
            function onLanguageChanged(event) {
                OpenPopupEx(event["language"]); // ==》接收到Qt语言改变的消息
                QCefClient.invokeMethod("JsGetLanguageChanged", 1, false, "arg3");//==>返回确认信息给Qt
            }
    
            /// 在页面加载时增加事件监听
            function onLoad() {
                if (typeof (QCefClient) == 'undefined') {
                    return;
                }
    
                // 增加颜色改变事件的监听
                QCefClient.addEventListener("colorChange", onColorChanged);
                QCefClient.addEventListener("languageChange", onLanguageChanged);
            }
    
            /// 在此说明,invokeMethod("funcname",...)中可以自定义传入多个参数类型
            /// 在Qt中将以QVariantList& arguments 变量接收 ==> eg: [arguments]: (QVariant(int, 1), QVariant(bool, false), QVariant(QString, "configurationTool"))
            function onInvokeMethodClicked() {
                QCefClient.invokeMethod("TestMethod", 1, false, "arg3");
            }
    
            /// 打开通讯配置工具
            function onOpenConfigurationTool() {
                QCefClient.invokeMethod("configurationTool", 1, false, "configurationTool");
            }
    
            /// 打开lua脚本编辑器
            function onOpenLuaEditor() {
                QCefClient.invokeMethod("openLuaEditor", 1, false, document.getElementById("luamessage").value);
            }
    
            function onDragAreaMouseDown() {
                QCefClient.invokeMethod("onDragAreaMouseDown");
            }
    
    
            /// 使用QCefQuery 发送信息给Qt
            function onQCefQueryClicked() {
                var query = {
                    request: document.getElementById("message").value,
                    onSuccess: function (response) {
                        alert(response);
                    },
                    onFailure: function (error_code, error_message) {
                        alert(error_message);
                    }
                }
                window.QCefQuery(query);
            }
    
    
            /**
             * getFuntionName()
             * @param {Function} func
             * @return {String}
             */
            function getFunctionName(func) {
                if (typeof func == 'function' || typeof func == 'object') {
                    var name = ('' + func).match(/function\s*([\w\$]*)\s*\(/);
                }
                return name && name[1];
            }
            /**
             * trace
             * @param [int] [count=10]
             * @return {String}
             */
            trace = function () {
                var stack = [],
                    caller = arguments.callee.caller;
    
                while (caller) {
                    stack.unshift(getFunctionName(caller));
                    caller = caller && caller.caller;
                }
                return 'functions on stack:' + '\n' + stack.join('\n');
            }
    
            function OpenPopup() {
                var popup = window.open("", "PopupWindow", "width=800, height=600");
                popup.document.write("<p>This is popup window.</p>");
            }
    
            function OpenPopupEx(msg) {
                var popup = window.open("", "PopupWindow", "width=800, height=600");
                popup.document.write("<p>" + msg + "</p>");
            }
    
    
        </script>
    </head>
    
    <body onload="onLoad()" id="main">
        <h1 align="center" style="font-size:12pt; font-family:MS Shell Dlg 2;">Web Area</h1>
        <!--<div align="center" id="dragarea" style="height:40px; background-color: gray; color: white;" onmousedown="onDragAreaMouseDown()">
            <span style="font-size:18pt; font-family:MS Shell Dlg 2;">you can drag this window in this area!</span>
        </div>-->
        <div align="center">
            <label> Test Case for InvokeMethod </label>
            <br />
            <input type="button" value="Invoke Method" onclick="onInvokeMethodClicked()" />
            <br />
            <br />
            <label> Test Case for QCefQuery </label>
            <br />
            <textarea id="message" style="width:320px; height:120px;">this message will be processed by native code.</textarea>
            <br />
            <input type="button" value="Query" onclick="onQCefQueryClicked()" />
            <br />
            <br />
            <label>Test Case for QCefUrlQuery</label>
            <br />
            <!--<a href="qcef://test/a/b">qcef://test/a/b</a>-->
            <a href="http://www.baidu.com/">百度</a>
            <br />
            <br />
            <button onclick="OpenPopup()">Open Popup</button> <input type="button" value="Open ConfigurationTool" onclick="onOpenConfigurationTool()" />
            <input type="button" value="Open LuaEditor" onclick="onOpenLuaEditor()" />
            <br />
            <textarea id="luamessage" style="width:600px; height:300px;">{"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" : ""}}}"
    </textarea>
            <br />
        </div>
    </body>
    </html>

    3、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(收)的一个通讯过程。

    4、JS发送消息给Qt:

    在QCefView封装中,我们可以看到,JS发送消息给Qt实际上是有三种方式的,这里我们只重点关注invokeMethod() 方法:

            function onOpenConfigurationTool() {
                QCefClient.invokeMethod("configurationTool", 1, false, "configurationTool");
            }
    

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

    method :   [ string ]   "configurationTool"

    arguments:  [ int ] 1

                        [ bool ]  false

                       [ string ]   "configurationTool"

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

     

    程序运行效果图:

    展开全文
  • 这里我使用最新的QWebEngineView,用QWebChannel实现Qt与js交互(官方推荐的)。 具体实现效果如下 点击c++ function callback按钮可实现js向Qt传信息 点击Alter实现Qt向js传信息 如果有兴趣可以到...

    网上的关于Qt实现百度离线地图的资源大多使用QtWebKit,而Qt5.6版本已经阉割了这部分内容。

    这里我使用最新的QWebEngineView,用QWebChannel实现Qt与js交互(官方推荐的)。

    具体实现效果如下


    点击c++ function callback按钮可实现js向Qt传信息


    点击Alter实现Qt向js传信息


    如果有兴趣可以到这里下载

    http://download.csdn.net/download/u013239402/10130327


    展开全文
  • Qt与JS交互

    2020-05-19 17:32:01
    QWebChannel *channel = new QWebChannel(this); bridge* pBridge = bridge::instance(); channel->registerObject("bridge",(*QObject)pBridge);...new QWebChannel(qt.webChannelTransport,function(channel)
    QWebChannel *channel = new QWebChannel(this);
    bridge* pBridge = bridge::instance();
    channel->registerObject("bridge",(*QObject)pBridge);
    ui.webView->page().setWebChannel(channel);
    
    
    var bridge;
    new QWebChannel(qt.webChannelTransport,function(channel){
         bridge = channel.objects.bridge;});
    myChart.on('click',function(param){
       bridge.clik=cknode(param.data.id);
    }
    
    展开全文
  • qt与js互相调用

    2016-09-03 14:23:00
    QT与JavaScript互调是通过QWebFrame的两个函数来实现的:addToJavaScriptWindowObject()将QObject对象传给JS,这样JS就能调用QObject的public slots函数。QT通过evaluateJavaScript()直接调用JS中的函数。流程如下...

    二、QT支持Js流程

    QT与JavaScript互调是通过QWebFrame的两个函数来实现的:addToJavaScriptWindowObject()将QObject对象传给JS,这样JS就能调用QObject的public slots函数。QT通过evaluateJavaScript()直接调用JS中的函数。流程如下(《QT高级编程》中插图):

     

     

     

    三、示例

    使用QWebKit创建一个包含浏览器和工具按钮窗口,在该浏览器中载入包括Js的html,工具按钮调用html中的js

    1、工程中引入 webkit

       工程文件中增加加:QT += webkit network

    2、载入html网页

    m_pWebView = new QWebView;

        m_pWebView->load(QUrl(tr("G:\\html特效示例\\jsTest.html")));

    3、开户js支持

        QWebSettings *pWebSettings = m_pWebView->page()->settings();       

        pWebSettings->setAttribute(QWebSettings::JavascriptEnabled,true);

    4、窗体布局

    //添加按钮    

        QPushButton *pEventBtn = new QPushButton(tr("QT Invok Js"));   

        QPushButton *pcloseBtn = new QPushButton(tr("close"));

    //布局:网页与按钮为上下布局,两按钮为水平居中布局  

     

        QHBoxLayout *pBtnLayout = new QHBoxLayout; 

        pBtnLayout->addWidget(pEventBtn);  

        pBtnLayout->addWidget(pcloseBtn);  

        pBtnLayout->setAlignment(Qt::AlignCenter);   

     

        QVBoxLayout *pMainLayout = new QVBoxLayout; 

       pMainLayout->addWidget(m_pWebView);  

        pMainLayout->addLayout(pBtnLayout);  

     

        QWidget *widget = new QWidget;  

        widget->setLayout(pMainLayout);  

        setCentralWidget(widget);

     

    5、建立信号与槽

    //每次载入html时发送段信号    

        connect(m_pWebView->page()->mainFrame(),SIGNAL(javaScriptWindowObjectCleared()),  this,SLOT(addObjectToJs()));    

    //按钮信号    

        connect(pEventBtn,SIGNAL(clicked()),this,SLOT(testJs()));    

        connect(pcloseBtn,SIGNAL(clicked()),this,SLOT(close()));

     

    6、JS调用QT中的public slots

    6.1、头文件中申明public slots:

    public slots:   

        void jsInvokQt();   

     

     

    6.2、将QObjectjs绑定

    void MainWindow::addObjectToJs()

    {

         m_pWebView->page()->mainFrame()->addToJavaScriptWindowObject("MainWindow",this);

    }

    6.3Js中调用QT jsInvokQt()函数

    function disp_qtmessage()

    {

            MainWindow.jsInvokQt();

    }

    7、QT调用JS函数disp_messagebox()

    void MainWindow::testJs()

    {    

        m_pWebView->page()->mainFrame()->evaluateJavaScript("disp_messagebox()");

    }

     

    四、附含JS的html源码:

    <html>

    <head>

    <script type="text/javascript">

    function disp_messagebox()

    {

    alert("This is javaScript MessageBox!")

    }

     

    function disp_qtmessage()

    {

      MainWindow.jsInvokQt();

       MainWindow.setInfor("Qt change string"); 

       alert(MainWindow.getInfor());

    }

     

    </script>

    </head>

    <body>

     

    <input type="button" οnclick="disp_qtmessage()" value="InvokQt" />

     

    </body>

    </html>

    转载于:https://www.cnblogs.com/lz20150121/p/5836947.html

    展开全文
  • Qt与JS相互调用

    千次阅读 2018-04-19 19:39:33
    Qt提供了本地C++对象JavaScript的无缝集成,可以进行本地web混合应用开发。利用Qt的Webkit集成与QtNetwork模块,可以自由的混合JavaScript、样式表、Web内容和Qt组件。对于C++和javaScript通信,最基本也最复杂...
  • Qt与JS数据交互

    千次阅读 2018-04-19 15:01:01
    QT版本:5.6.2核心类:QWebEngineView, QWebChannel 1、C++和HTML通过websocket通信,通过官方的 qwebchannel.js 实现。2、C++和HTML共用一个对象并以此进行通信,即通过QWebChannel的registerObject函数。void ...
  • 最清晰Qt与JS通过qwebchannel交互例子

    万次阅读 多人点赞 2019-03-20 11:01:01
    Qt平台上有很多很棒的图表控件,比如QWT,QCustomPlot,以及Qt5.5以后自带的QChart,但与JS网页端的各种绚丽效果控件比,还是差了不少。这次就是打算把百度出品的EChart控件应用在Qt端。 而在这样的跨平台调用中,...
  • Qt与JS(三)

    2017-09-22 20:49:00
    Qt不错的学习网址: ... ---------------------------------------------------- ...IE内核,qt调用jsqt写com组件,html就可以调用qt 可以百度 QAxBindable 会搜索到比较有用的文章 http://blo...
  • 回到正题,这次项目涉及到的东西很杂,其中涉及到了要绘制图表,我之前用的比较熟练的是Qt自带的QtChart,但这次Qt开发工具是5.5版本的,而 5.7才自带这个工具;所以根据当时的资源,选择了ECharts,上手快,图表...
  • qt与js/html进行值传递

    千次阅读 2017-06-13 14:27:18
    qt与html之间的传值
  • QT += webenginewidgets webchannel //地图布局 m_webView = new QWebEngineView(this); QStackedLayout* layout = new QStackedLayout(ui->frame); ui->frame->setLayout(layout); layout->...
  • Qt JS 之间如何交互

    2013-03-26 21:13:59
    QtWebkit的javascript里访问QObject的最关键的关键就是下面这个方法:void QWebFrame::addToJavaScriptWindowObject ( const QString &name,QObject *object ) 我们要在js调用该QObject之前调用这个函数。 这个...
  • 获得了照片的GPS信息后,我们现在要做的就是把GPS信息传入JS中,然后通过百度地图API将轨迹绘制出来。 一:在程序页面加载地图 qt5.6及之后取消了QWebkits,转为使用QWebEngine. 在qt5.6的额ui设计师界面中,并不...

空空如也

空空如也

1 2 3 4 5 ... 17
收藏数 325
精华内容 130
关键字:

qt与js