• QwebKit使用心得


    最近这段时间,正在用QWebkit开发一个Application store的项目。因为需要用到第三方的数据,但后台无法直接去获取,所以需要做一个底层的模块,去获取第三方数据,然后给网页调用,因此我们选取了以WebKit为引擎的QWebkit来开发我们的项目。

    在开发中,获得了一些心得体会,写下来供大家参考。为了方便说明,我特意做了一个例子。

                                                       (图1)

    此例子中,左边显示网页,右边是控件部分。

    用户在网页的Name和Password输入框输入内容后,点击"Submit"按钮,则右边的Name和Password框则会出现网页中的内容,这就是网页调用Qt模块。

    而用户在右边输入分别输入Name和Password,点击"Call JS"后,输入的信息也会显示在左边的Name和Password栏。这就是Qt调用网页。

    由此我们可以看出QWebKit,即可以Qt调用网页,也可以网页调用Qt。这样我们就可以做用Qt做一些网页做不了的事情。

    接下来,将阐述如何实现Qt和网页互相调用。

    首先,在“图1”所示的主界面中生成WebKit控件,可以自己new或者在Design中拖入。在本例中,采取的是拖入此控件。此控件对应的类是QWebView。它可以Load和显示页面。通过此控件我们来调用网页的方法和接受网页的调用。

    本主界面的类是

    #include <QtGui/QDialog>
    #include "ui_qwebkittest.h"
    #include "mywebkit.h"
    
    class QWebKitTest : public QDialog
    {
        Q_OBJECT
    
    public:
        QWebKitTest(QWidget *parent = 0, Qt::WFlags flags = 0);
        ~QWebKitTest();
    
        void setValueFromWeb(const QString &strName,const QString &strPwd);
    
    protected slots:
        void onBtnCallJSClicked();
        void populateJavaScriptWindowObject();
    
    private:
        Ui::QWebKitTestClass ui;
        MyWebKit m_webObj;
    };

    而WebKit控件则是

    class Ui_QWebKitTestClass
    {
    public:
        QWebView *webView;


    主界面通过下面的形式调用。

    ui.webView

    接下来我们将用ui.webView来见证奇迹诞生的时刻。

    首先我们先来弄清楚第一个问题,怎么将Qt和网页联系起来,使之能够互相调用?

    估计这是大部分看官最关心的吧。嗯,好吧。

    广告时间到

    各位看官也来看看这个帖子吧,Qt的Signal和Slot机制(一),给鄙人攒点人气,谢了再见

    Qt使用的是向网页注册一个QObject对象,通过这个对象,网页可以通过这个调用这个对象的方法来实现调用底层的逻辑。

    以下是本例中的注册对象的声明,

    class MyWebKit : public QObject
    {
        Q_OBJECT
    
    public:
        MyWebKit(QObject *parent);
        ~MyWebKit();
    
    public slots:
    
        void onCall(QString strName,QString strPwd);
       
    private:
        
    };


    而Qt则通过,调用下列方法把注册对象注入到网页中,

    ui.webView->page()->mainFrame()->
    addToJavaScriptWindowObject(QString("mywebkit"),&m_webObj);
    

    注册过程如下,

        ui.webView->setUrl((QUrl("qrc:/form.html"));
        ui.webView->page()->mainFrame()->addToJavaScriptWindowObject(QString("mywebkit"),&m_webObj);

    看官注意,m_webObj就是注入到网页中的QObject对象,而"mywebkit"是此对象在网页中的名字。在网页中,“mywebkit"就代表着m_webObj,被当作一个javascript对像来调用。具体细节请看下列网页代码,

      <html>
        <head>
          <title>Login page</title>
          
            <script language="javascript" >
            function calltoqt()
            {
              var nameArray;
              nameArray = document.getElementsByName("username");
              var pwdArray;
              pwdArray = document.getElementsByName("userpwd");
              window.mywebkit.onCall(nameArray[0].value,pwdArray[0].value);
             
            }
    
            function callfromqt(name,pwd)
            {
                var nameArray;
                nameArray = document.getElementsByName("username");
                var pwdArray;
                pwdArray = document.getElementsByName("userpwd");
                nameArray[0].value = name;
                pwdArray[0].value = pwd;
            }
           
          </script>
          
        </head>
        <body>
            <p align="center">Name:
            <input type="text" name="username" />
            </p>
          
            <p align="center">Password:
            <input type="text" name="userpwd"  />
            </p>
            <p align="center" >
            <input type="button" value="Submit" onclick="calltoqt()" />
            </p>
        </body>
      </html>


    在此网页中,当用户点击图1中的左边网页的Submit按钮时,就会调用calltoqt的javascript方法。在calltoqt中,我们获取了username和userpwd的值后,就调用window.mywebkit.onCall的方法,来通知底层Qt模块,这里的mywebkit就是我们刚注册的m_webObj,OnCall就是MyWebKit类的成员函数。当网页调用这个函数时,Qt模块的MyWebKit::OnCall函数就会被调用。代码如下:

    void MyWebKit::onCall(QString strName,QString strPwd)
     {
        QWebKitTest *pMain = (QWebKitTest*)parent();
        pMain->setValueFromWeb(strName,strPwd);
     }

    在此函数中,MyWebKit会调用主界面(QWebKitTest)的setValueFromWeb方法,将网页中的Name和Password栏的内容放到右边的Name和Password控件中显示出来。

    代码如下,

     void QWebKitTest::setValueFromWeb(const QString &strName,const QString &strPwd)
      {
          ui.textEdit_name->setText(strName);
          ui.textEdit_pwd->setText(strPwd);
      }

    但是不是所注册对象的成员函数都可以被调用呢?答案是否定的,只有Slot函数才能被网页调用,其他的则不能。因为这是一个signal-slot过程

    Qt是如何调用网页的呢?我们来看以下的例子。

    当用户在右边的Name和Password控件填入内容后,点击"Call JS"按钮,Qt就调用evaluateJavaScript函数来改变网页的行为。具体代码如下,

    void QWebKitTest::onBtnCallJSClicked()
     {
        QString strVal = QString("callfromqt(\"%1\",\"%2\");").arg(ui.textEdit_name->toPlainText()).arg(ui.textEdit_pwd->toPlainText() );
        ui.webView->page()->mainFrame()->evaluateJavaScript(strVal);
     }

    我们可以看到evaluateJavaScript的参数,实际上就是一段javascript代码(callfromqt("andrei","12345");)。Qt底层模块通过evaluateJavaScript调用了网页中的"callfromqt"方法

     function callfromqt(name,pwd)
            {
                var nameArray;
                nameArray = document.getElementsByName("username");
                var pwdArray;
                pwdArray = document.getElementsByName("userpwd");
                nameArray[0].value = name;
                pwdArray[0].value = pwd;
            }


    使右边的Name和Password控件中的值,赋到了左边网页中Name和Password的输入框中。

    当然,evaluateJavaScript的参数不一定只是javascript方法,同样一段javascript代码也是可以的。比如以上功能也可以这样调用

     ui.webView->page()->mainFrame()->evaluateJavaScript(" var nameArray; \
                nameArray = document.getElementsByName(\"username\"); \
                var pwdArray; \
                pwdArray = document.getElementsByName(\"userpwd\"); \
                nameArray[0].value = \"andrei\"; \
                pwdArray[0].value = \"123456\";" );

    但这就是QWebKit的全部真相吗?

    请听下回分解

    注明:此文章本人在CSDN上同步发布。

  • 相关阅读:
    jekins接通gitee的webhook做自动部署 vue、react、java、springBoot
    vue可复用性 & 组合
    vite使用短链接
    Ubuntu12.04(X86_64)上安装Mesa8.0.4
    回调函数
    c#隐式转换
    OpenGL ES2 的OffScreen实现
    Catch exception from other thread
    C# []、List、Array、ArrayList 区别及应用
    redhat update
  • 原文地址:https://www.cnblogs.com/andreitang/p/2125166.html
Copyright © 2020-2023  润新知