Qt與Javascript互動架構設計 .

來源:互聯網
上載者:User

[-]

  1. Qt和Javascript互動的兩種方式
  2. 執行個體分析
    1. 前端——HTML和Javascript
    2. 後台——Qt
  3. 小結
  4. 附錄

轉載請註明出處:http://blog.csdn.net/footman_/article/details/6694161

目錄

1 Qt和Javascript互動的兩種方式

2 執行個體分析

       2.1 前端——HTML和Javascript

       2.2 後台——Qt

3 小結

4 附錄

1 Qt和Javascript互動的兩種方式

        為了充分發揮Javascript的跨平台特性,Qt和JavaScript互動將不採用“Qt對Javascript公開對象引用”的方式(即通過QWebFrame的addToJavaScriptWindowObject方法向Javascript提供對象引用)。這種方式雖然使得Qt和JavaScript能直接的互動,但是Javascript端對於Qt端的依賴將影響Javascript發揮跨平台性。該方式調用原理1-1中左圖所示:

  

圖1-1

        不難看出,左邊的方式中Javascript對Qt對象的依賴不利於Javascript往其它平台移植。

        而右邊的“自訂URL”方式則不一樣,Javascript不再選擇利用Qt對象去調用Qt方法,而是直接向Webkit瀏覽器發送自訂URL,Webkit捕獲到URL後通過QWebKit自身提供的Signal來關聯Qt中的Slots函數,並向Slots函數傳遞URL,Slots函數就可以根據URL中的資訊作出相應處理。在“自訂URL”方式中,底層平台不論是Qt,還是Android,上層的Javascript只需發送“自訂URL”即可。這樣Javascript的平台無關性就能得以充分發揮。1-2所示:

圖1-2

2執行個體分析

         對“自訂URL”方式有了初步認識後,下面通過一個執行個體來敘述這種“自訂URL”的方式中可能涉及到的技術點。

2.1 前端——HTML和Javascript

         例子中涉及2個html檔案a.html、b.html和一個Javascript檔案js.js。檔案b.html很簡單,就是一句歡迎語,檔案a.html運行2-1所示:

圖2-1

其對應的代碼如下:

<html>

<script language="JavaScript" type="text/javascript" src="js.js"></script>

<body>

         <center>

                            <span>text a:</span>

                            <input type="text" name="aText" id="aText" />

                            <input type="submit" value="Go" onclick="javascript:sendURL()" />

                            <a href="b.html">b.html</a>

                       <font color=red><div id=warning></div></font>

         </center>

</body>

</html>

該html檔案中引用到的js.js代碼如下:

function sendURL()

{

         var value = document.getElementById("aText").value.replace(/\s/g,"");

         if(value != "")

         {

                   if(confirm("Go to " + value +"?"))

                   {

                            location.href = value;

                   }

         }

         else

         {

                   document.getElementById("warning").innerHTML = "Please Input Target";

         }

}

2.2 後台——Qt

         從a.html和js.js端的代碼不難看出,當使用者在a.html頁面上文字框內輸入內容後,點擊“Go”按鈕就會觸發js.js中的sendURL方法,該方法會把使用者在文字框內輸入的內容當作URL發送,那麼背景Qt端如何得到這個URL呢?

2.2.1 loadStarted訊號

         通過查閱Qt協助文檔找到這樣一個訊號——loadStarted(),該訊號在QWebView、QWebPage和QWebFrame均存在。當開始載入一個新的網頁時產生該訊號,所以接收Javascript產生的URL可以嘗試從該訊號入手。

2.2.2 requestedUrl函數

         QWebFrame有個方法叫做requestedUrl()。當產生URL請求而載入Web頁面時,調用該方法能過擷取到請求的URL。看來接收Javascript產生的URL,這個方法不可或缺。

2.2.3 擷取URL

      下面結合前面選擇的訊號和方法來擷取Javascript產生的URL。

1、為loadStarted訊號設定Slots函數

QWebPage * page = view->page();

connect(page, SIGNAL(loadStarted()), this, SLOT(doLoad()));

2、接收URL

void MyMainWindows::doLoad()

{

    QUrl url = view->page()->mainFrame()->requestedUrl();

    qDebug()<<"doLoad...."<<url;

    /*解析URL*/

    parseURL(url);

}

parseURL的具體實現參見附錄。

2.2.4 示範執行個體

        接收成功後,就可以由Qt解析URL,由URL中的資訊來選擇應該執行什麼操作。

        在本例子中,如果URL是字串“print”,那麼就調用“print”相關模組(簡單的輸出資訊,然後跳轉到b.html頁面)。圖2-2為執行個體運行後的主介面:

圖2-2

        輸入print,點擊“Go”按鈕,介面切換,2-3所示:

圖2-3

        同時觀察控制台輸出,2-4所示:

圖2-4

        從輸出資訊中可以看出,接收到的URL為檔案絕對路徑,解析後比較URL,如果等於“print”,那麼就執行“Call Moudle Of Print”,並載入b.html。

        注意,載入b.html頁面時同樣會因為產生loadStarted訊號而執行預先設定好的Slots函數。至此示範完畢!

3小結

         在小結之前先來看a.html中埋下的一個小伏筆。

         在a.html中有個超連結“b.html”,該連結的URL指向b.html頁面,正常情況下點擊該連結就會跳轉到b.html頁面,但為何在本執行個體程式中點擊b.html不會有任何跳轉呢?

         這其中的原因在於QWebKit中的linkClicked訊號,當點擊Web頁面中的超連結時就會產生該訊號。本例中為該訊號設定Slots函數,函數中沒有對超連結的URL進行載入,所以點擊超連結後不會產生任何跳轉。類似於linkClicked這樣的訊號還有很多,可以根據不同的需求選擇使用。

        對比兩種互動方式,“Qt對Javascript公開對象引用”的方式在Javascript調用Qt的過程中表現得較為直接,而“自訂URL”的互動方式很好地解決了跨平台問題。總之,方案沒有好壞之分,各有所長,根據實際需求選取即可。

4附錄

1、parseURL方法具體實現如下:

void MyMainWindows::parseURL(QUrl url)

{  

    QString urlStr = url.toString();

    qDebug()<<"parseURL...."<<urlStr;

 

    /*

     * 因為每次調用load都會觸發loadStarted訊號而執行該方法,

     * 所以必須保證load網頁時不會解析URL,否則load不到網頁。

     */

    if(urlStr.right(5).operator != (QString(".html")))

    {

        int len = urlStr.length();

        qDebug()<<"urlStr.length():"<<len;

 

        QString ret = urlStr.right(len-24);

        qDebug()<<"Start Parse Url:"<<ret;

 

        if(ret.operator==(QString("print")));

        {

            qDebug()<<"Call Moudle Of Print";

 

            /*如果找不到該url,app exited with code -1073741819*/

            view->load(QUrl("../b.html"));

        }

    }

}

 

2、使用linkClicked訊號前必須調用setLinkDelegationPolicy:

page->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);

connect(page, SIGNAL(linkClicked(QUrl)), this, SLOT(parseURL(QUrl)));

轉載請註明出處:http://blog.csdn.net/footman_/article/details/6694161

目錄

1 Qt和Javascript互動的兩種方式

2 執行個體分析

       2.1 前端——HTML和Javascript

       2.2 後台——Qt

3 小結

4 附錄

1 Qt和Javascript互動的兩種方式

        為了充分發揮Javascript的跨平台特性,Qt和JavaScript互動將不採用“Qt對Javascript公開對象引用”的方式(即通過QWebFrame的addToJavaScriptWindowObject方法向Javascript提供對象引用)。這種方式雖然使得Qt和JavaScript能直接的互動,但是Javascript端對於Qt端的依賴將影響Javascript發揮跨平台性。該方式調用原理1-1中左圖所示:

  

圖1-1

        不難看出,左邊的方式中Javascript對Qt對象的依賴不利於Javascript往其它平台移植。

        而右邊的“自訂URL”方式則不一樣,Javascript不再選擇利用Qt對象去調用Qt方法,而是直接向Webkit瀏覽器發送自訂URL,Webkit捕獲到URL後通過QWebKit自身提供的Signal來關聯Qt中的Slots函數,並向Slots函數傳遞URL,Slots函數就可以根據URL中的資訊作出相應處理。在“自訂URL”方式中,底層平台不論是Qt,還是Android,上層的Javascript只需發送“自訂URL”即可。這樣Javascript的平台無關性就能得以充分發揮。1-2所示:

圖1-2

2執行個體分析

         對“自訂URL”方式有了初步認識後,下面通過一個執行個體來敘述這種“自訂URL”的方式中可能涉及到的技術點。

2.1 前端——HTML和Javascript

         例子中涉及2個html檔案a.html、b.html和一個Javascript檔案js.js。檔案b.html很簡單,就是一句歡迎語,檔案a.html運行2-1所示:

圖2-1

其對應的代碼如下:

<html>

<script language="JavaScript" type="text/javascript" src="js.js"></script>

<body>

         <center>

                            <span>text a:</span>

                            <input type="text" name="aText" id="aText" />

                            <input type="submit" value="Go" onclick="javascript:sendURL()" />

                            <a href="b.html">b.html</a>

                       <font color=red><div id=warning></div></font>

         </center>

</body>

</html>

該html檔案中引用到的js.js代碼如下:

function sendURL()

{

         var value = document.getElementById("aText").value.replace(/\s/g,"");

         if(value != "")

         {

                   if(confirm("Go to " + value +"?"))

                   {

                            location.href = value;

                   }

         }

         else

         {

                   document.getElementById("warning").innerHTML = "Please Input Target";

         }

}

2.2 後台——Qt

         從a.html和js.js端的代碼不難看出,當使用者在a.html頁面上文字框內輸入內容後,點擊“Go”按鈕就會觸發js.js中的sendURL方法,該方法會把使用者在文字框內輸入的內容當作URL發送,那麼背景Qt端如何得到這個URL呢?

2.2.1 loadStarted訊號

         通過查閱Qt協助文檔找到這樣一個訊號——loadStarted(),該訊號在QWebView、QWebPage和QWebFrame均存在。當開始載入一個新的網頁時產生該訊號,所以接收Javascript產生的URL可以嘗試從該訊號入手。

2.2.2 requestedUrl函數

         QWebFrame有個方法叫做requestedUrl()。當產生URL請求而載入Web頁面時,調用該方法能過擷取到請求的URL。看來接收Javascript產生的URL,這個方法不可或缺。

2.2.3 擷取URL

      下面結合前面選擇的訊號和方法來擷取Javascript產生的URL。

1、為loadStarted訊號設定Slots函數

QWebPage * page = view->page();

connect(page, SIGNAL(loadStarted()), this, SLOT(doLoad()));

2、接收URL

void MyMainWindows::doLoad()

{

    QUrl url = view->page()->mainFrame()->requestedUrl();

    qDebug()<<"doLoad...."<<url;

    /*解析URL*/

    parseURL(url);

}

parseURL的具體實現參見附錄。

2.2.4 示範執行個體

        接收成功後,就可以由Qt解析URL,由URL中的資訊來選擇應該執行什麼操作。

        在本例子中,如果URL是字串“print”,那麼就調用“print”相關模組(簡單的輸出資訊,然後跳轉到b.html頁面)。圖2-2為執行個體運行後的主介面:

圖2-2

        輸入print,點擊“Go”按鈕,介面切換,2-3所示:

圖2-3

        同時觀察控制台輸出,2-4所示:

圖2-4

        從輸出資訊中可以看出,接收到的URL為檔案絕對路徑,解析後比較URL,如果等於“print”,那麼就執行“Call Moudle Of Print”,並載入b.html。

        注意,載入b.html頁面時同樣會因為產生loadStarted訊號而執行預先設定好的Slots函數。至此示範完畢!

3小結

         在小結之前先來看a.html中埋下的一個小伏筆。

         在a.html中有個超連結“b.html”,該連結的URL指向b.html頁面,正常情況下點擊該連結就會跳轉到b.html頁面,但為何在本執行個體程式中點擊b.html不會有任何跳轉呢?

         這其中的原因在於QWebKit中的linkClicked訊號,當點擊Web頁面中的超連結時就會產生該訊號。本例中為該訊號設定Slots函數,函數中沒有對超連結的URL進行載入,所以點擊超連結後不會產生任何跳轉。類似於linkClicked這樣的訊號還有很多,可以根據不同的需求選擇使用。

        對比兩種互動方式,“Qt對Javascript公開對象引用”的方式在Javascript調用Qt的過程中表現得較為直接,而“自訂URL”的互動方式很好地解決了跨平台問題。總之,方案沒有好壞之分,各有所長,根據實際需求選取即可。

4附錄

1、parseURL方法具體實現如下:

void MyMainWindows::parseURL(QUrl url)

{  

    QString urlStr = url.toString();

    qDebug()<<"parseURL...."<<urlStr;

 

    /*

     * 因為每次調用load都會觸發loadStarted訊號而執行該方法,

     * 所以必須保證load網頁時不會解析URL,否則load不到網頁。

     */

    if(urlStr.right(5).operator != (QString(".html")))

    {

        int len = urlStr.length();

        qDebug()<<"urlStr.length():"<<len;

 

        QString ret = urlStr.right(len-24);

        qDebug()<<"Start Parse Url:"<<ret;

 

        if(ret.operator==(QString("print")));

        {

            qDebug()<<"Call Moudle Of Print";

 

            /*如果找不到該url,app exited with code -1073741819*/

            view->load(QUrl("../b.html"));

        }

    }

}

 

2、使用linkClicked訊號前必須調用setLinkDelegationPolicy:

page->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);

connect(page, SIGNAL(linkClicked(QUrl)), this, SLOT(parseURL(QUrl)));

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.