天天看點

利用QT進行web與本地混合應用開發-轉載

[T] 利用QT進行web與本地混合應用開發

 Qt Features for Hybrid Web/Native Application Development。

原文參見 

http://www.qtsoftware.com/forms/whitepapers/reg-whitepaper-hybrid

. (限于本人英文水準,隻譯其大概)

Qt提供了本地 C++對象與JavaScript的無縫內建,是進行本地與web混合應用開發的理想平台。

(一)Qt Webkit 內建

 

 利用Qt的Webkit 內建與QtNetwork子產品,你完全可以進行本地桌面與web混合應用開發,你可以自由地混合JavaScript,樣式表,Web内容和Qt元件。 Webkit是一個非常成熟的web浏覽引擎。Qt中內建了這個大名鼎鼎的引擎,通過QtWebkit,你可以在C++ 中執行JavaScript,或者在網頁中內建C++對象,并且通過JavaScript和這些對象進行互動。

  一個現代的HTML渲染引擎隻

是混合開發的一半,另一半就是本地應用和渲染對象的互動。QT的Webkit 內建提供了這種解決方案:

  1.使用object标簽嵌入Qt Widgets元件。這可以讓使用C++代碼的Qt元件包含在網頁中,作為網頁的部分外觀。

  2.在JavaScript中通路C++對象。你

可以在JavaScript環境中插入C++對象,讓網頁腳本直接通路你的資料結構。

  3.在Qt中執行JavaScript。你可以在C++ 調用網頁環境中的JavaScript函數,觸發網頁事件。

  4.共享用戶端存儲。在JavaScript和C++中你都具有通路資料庫的能

力,這樣當下線時也能共享大量資料。

(二)與嵌入的Qt對象互動

  使用 QWebView 元件,有兩種方法可以在網頁中嵌入C++對象。你可以在網頁的JavaScript中添加C++對象,或者也可以建立一個插件,然後在網頁中使用 object标簽嵌入。

  

  第二種方法更容易入手。當在網頁中放入 Widget元件時,它的所有public slots就像普通函數一樣被網頁中的JavaScript函數通路。

    要在網頁中添加一個Widget,首先要告訴你的QWebPage對象,該Widget可用,這個通過子類化QWebPlugFactory完成,你需要

重新實作兩個方法:plugs和create。plugs方法通知網頁該Widget可用,create方法根據請求建立widget。

  在 HTML網頁中,widgets使用object标簽建立。比如,下面這個标簽試圖建立一個 application/x-qt-colorlabel 元件。

<object type="application/x-qt-colorlabel" width="50px" height="20px" id="label" />

  要利用這種建立,必須要允許使用插件并且要告訴QWebpage插件的工廠類。在下面的代碼中,ColorLabelFactory将 會根據application/x-qt-colorlabel的請求建立相應執行個體。

QWebSettings::globalSettings()->setAttribute(QWebSettings::PluginsEnabled, true); 

webView->page()->setPluginFactory(new  ColorLabelFactory(this));

  ColorLabel有一個公開的slot: chagneColor(),這個對于網頁中的JavaScript自動可用。在網頁中插入一個指向該元素的連結,可以以一種簡單的方式激活C++函數。

<a href='javascript:document.getElementById("label").changeColor();'>Change color!</a> 

  要反方向推進事件,必須要使你的對象在JavaScript文檔上下文中可用。要對QWebPage的每一個 QWebFrame,調用addToJavaScriptWindowObject方法。這個方法允許你根據名字把一個對象添加到JavaScipt上下 文中。

webView->page()->mainFrame()->addToJavaScriptWindowObject( "eventSource", new eventSource( this ) );

  要連接配接剛添加對象eventSource的信号,要加上一段JavaScript代碼,使用evaluateJavaScript方法 完成。下面的代碼将把eventSource對象的signalName信号連接配接到一個JavaScript函數destFunction。

利用QT進行web與本地混合應用開發-轉載

webView->page()->mainFrame()->evaluateJavaScript( "eventSource.signalName.connect(destFunction);" );

  如果你把一個對象添加到一個以标準浏覽器檢視的JavaScript頁面中,有一個信号需要知道。每一次JavaScript 内容被清除,Frame都會釋放 javaScriptWindowObjectCleared 信号。為了使你的Qt對象一直可用,你需要連接配接這個信号,并且在這裡調用 addToJavaScriptWindowObject函數。

(二)使用用戶端存儲共享資料

       随着HTML5,WEB标準日益靠近于桌面,同樣,桌面也開始內建WEB。這方面一個最大的變化就是用戶端存儲。這在客戶機上給了每一方(比如每一個頁 面)一個能利用SQL的資料庫引擎,可以快取區域資料,減少流量,使頁面能脫機使用。還可以用來存儲大量的結構化的,可搜尋的資料。

      用戶端存儲可以在JavaScript中使用,從JavaScript代碼中搜尋資料庫,然後從搜尋結果中生成頁面。這要使用 openDatabase和transaction函數。

假設現在有個資料庫, 代碼如下所示:

db = openDatabase("TestDb ", "1.0", "Client side storage test", 200000);

db.transaction(function(tx) {

      tx.executeSql("SELECT id, text FROM Texts", [], function(tx, result) {

          for (var i = 0; i < result.rows.length; ++i) {

              var row = result.rows.item(i);

               processText( row['id'], row['text'] );

         }

    },    function(tx, error) {

         alert('Failed to retrieve texts from the database - ' + error.message);

         return;

    });

});

     使用QtWebkit,你可以使用QtSql子產品通路同一個資料庫。這在混合開發中是一個非常有用的特征。比如,你的應用中的web頁面在和本地部分共享 資料時,可以用同樣的機制來儲存資料。

     為了避免安全問題,用戶端的資料庫隻能由具有正确權限的一方在JavaScript中通路。本地的C++代碼也可以通過靜态的QWebSecurityOrigin::allOrigins 方法,或者通過QWebFrame::securityOrigin 來通路所有安全對象。

       通過databases方法,可以通路一個 QWebDatabaew方法清單,每一個web資料庫對象有一個filename屬性,可以用來在本地代碼中通路資料庫。

QWebDatabase webdb = mySecurityOrigin.databases()[index];

QSqlDatabase sqldb = QSqlDatabase::addDatabase("QSQLITE", "webconnection");

sqldb.setDatabaseName(webdb.fileName());

if (sqldb.open()) {

    QStringList tables = sqldb.tables();

利用QT進行web與本地混合應用開發-轉載

}

         在WEB和本地應用連接配接事件的能力,再加上共享資料的機制,更易于模糊WEB和桌面之間的界限。

(三)WEB轉換

       很多通過WEB得到的資料并不适合直接顯示。比如網絡新聞, 地理資料,以及其它特定資料格式的應用。QT的網絡子產品可以以一種很簡單的方式下載下傳這樣的資料,然後解析資料,把它轉換成能被自己的代碼處理的合适的格 式。也可以通過QtXmlPatterns子產品處理,當輸出格式是XML或者想在XHMTL網頁中顯示時,這樣更加友善。

      我們通過一個小例子來大緻了解一下這個有意思的部分。我們下載下傳一個新聞源,用XSLT把它從XML轉換成XHTML,然後通過QWebPage把它顯示出 來。(圖略)

      QNetworkAccessManager 類讓你很容易處理用戶端和WEB伺服器之間的互動。它幫你處理諸如代理,儲存設定,COOKIE以及SSL會話這些細節。總之,它不但讓你在象上傳下載下傳這

些常見情況更加容易,還可以幫你處理登入,認證這些複雜會話。

    為了下載下傳我們例子中的新聞源,我們所有要做的就是建立一個QNetworkAccessManager 然後調用它的get方法。結果通過 finished(QNetworkReply*) 信号傳回。

{

利用QT進行web與本地混合應用開發-轉載

QNetworkAccessManager *manager = new QNetworkAccessManager( this );

connect( manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(handleReply(QNetworkReply*)) );

connect( manager, SIGNAL(finished(QNetworkReply*)), m_progressBar, SLOT(hide()) );

QNetworkReply *reply = manager->get( QNetworkRequest( QUrl( feedUrl ) ) );

connect( reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(updateProgress(qint64,qint64)) );

未完。。。。