Qt webKit可以做什麼(四)——實現本地QObject和JavaScript交互

上一篇我們瞭解瞭如何在webkit中創建含有web內容的本地應用。這一篇我們將實現JavaScript和本地的QObject的交互。在閱讀本篇之前需要對Qt的信號和槽機制和JavaScript有簡單的瞭解。
Qt本地對象和JavaScript交互分爲三個步驟

    1. 將本地QObject暴露給webkit和JavaScript
    2. 將本地QObject的信號和JavaScript的槽連接起來
    3. 通過JavaScript調用本地QObject的槽

 

Picture6.png

 

也就是第1步和第2步結合起來實現 本地QObject的信號和JavaScript的槽連接
第1步和第3步結合起來實現 通過JavaScript調用本地QObject的槽

下面我們就分別看一下第1、2、3步分別如何實現的。

1、將本地QObject暴露給Webkit。主要分爲以下幾個步驟。

    1. 新建一個QObject, 命名爲simpleQObject,包含信號和槽。其頭文件如下:
          1. #include <QtCore/QObject>
          2. #include <QtCore/QMap>
          3. #include <QtCore/QString>
          4. #include <QtCore/QVariant>
          5. class SampleQObject : public QObject
          6. {
          7. Q_OBJECT
          8. public:
          9. SampleQObject(QObject *parent = 0);
          10. signals: /* 聲明QObject signals */
          11. void signal(QMap<QString, QVariant> object);
          12. public slots: /*聲明 QObject slots */
          13. QMap<QString, QVariant> slotThatReturns(const QMap<QString,
          14. QVariant>& object); //QObject 的槽,用來返回字符串
          15. void slotThatEmitsSignal(); //QObject的槽,用來發射信號,並且記錄發射次數
          16. private:
          17. int m_signalEmited;
          18. QMap<QString, QVariant> m_returnObject;
          19. QMap<QString, QVariant> m_emitSignal;
          20. };
    2. 創建實現函數。mainwindow.h 和 mainwindow.cpp。 mainwindow.h代碼如下
          1. #include <QMainWindow>
          2. #include "sampleqobject.h“
          3. class MainWindow : public QMainWindow {
          4. Q_OBJECT
          5. public:
          6. MainWindow(QWidget *parent = 0);
          7. ~MainWindow();
          8. private slots:
          9. /*聲明 將 QObject 暴露給 Qt WebKit 的函數*/
          10. void addJavaScriptObject();
          11. protected:
          12. void changeEvent(QEvent *e);
          13. private:
          14. Ui::MainWindow *ui;
          15. SampleQObject* m_sampleQObject;
          16. };
    3. mainwindow.cpp關鍵代碼如下:
          1. //當網頁被載入或者刷新時,將暴露給webkit的QObject和webkit JavaScript連接
          2. connect(ui->webView->page()->mainFrame(),
          3. SIGNAL(javaScriptWindowObjectCleared()),
          4. this, SLOT(addJavaScriptObject()));
          1. void MainWindow::addJavaScriptObject()
          2. {
          3. //addJavaScriptObject函數的實現:將simpleQObject和webkit JavaScript連接
          4. this->ui->webView->page()->mainFrame()->addToJavaScriptWindowObject
          5. ("sampleQObject“, this->m_sampleQObject);
          6. }

2. 將本地QObject的信號和JavaScript的槽連接起來

 

Picture7.png

 

    1. 如何發射QObject信號。
          1. signals:
          2. void signal(QMap<QString, QVariant> object);
          3. public slots:
          4. void slotThatEmitsSignal();
          5. /* this slot is designed to emit signals and count emit times*/
          6. void SampleQObject::slotThatEmitsSignal()
          7. {
          8. qDebug() << "SampleQObject::slotThatEmitsSignal";
          9. this->m_signalEmited++; /* count emit times */
          10. this->m_emitSignal.clear();
          11. this->m_emitSignal["signalsEmited"] = QVariant(this->m_signalEmited);
          12. this->m_emitSignal["sender"] = QVariant("SampleQObject::slotThatEmitsSignal");
          13. qDebug() << "SampleQObject::slotThatEmitsSignal" << this->m_emitSignal;
          14. /* 發射信號 */
          15. emit signal(this->m_emitSignal);
          16. }
    2. JavaScript槽的實現
          1. $(document).ready(function() {
          2. try {
          3. /* 將sampleQObjects的signal 和 JavaScript slot 連接起來*/
          4. sampleQObject.signal.connect(slot);
          5. /* 當simpleQObject發射信號時調用JavaScript的槽 */
          6. sampleQObject.slotThatEmitsSignal();
          7. }
          8. catch(e) {
          9. alert(e);
          10. }
          11. });
          12. /* slot函數將會輸出 SimpleQObject has emited signal ? times */
          13. function slot(object) {
          14. var objectString = object.sender +
          15. " has emited signal " +
          16. object.signalsEmited +
          17. " times.";
          18. alert(objectString);
          19. }
    3. Run the app。

 Picture8.png

 


當點擊刷新時,彈出新的對話框:


Picture9.png

 

3. 通過JavaScript調用本地QObject的槽


Picture10.png

 

    1. JavaScript信號發射
          1. try {
          2. var object = {intValue: 1};
          3. /* 聲明一個JavaScript object並用simpleQObject的槽的返回值賦值它*/
          4. var returnedObject = sampleQObject.slotThatReturns(object);
          5. /* 輸出 "1 added bonus"*/
          6. alert(returnedObject.stringValue);
          7. }
    2. QObject 槽函數
          1. QMap<QString, QVariant> SampleQObject::slotThatReturns(const QMap<QString, QVariant>& object)
          2. {
          3. qDebug() << "SampleQObject::slotThatReturns";
          4. this->m_returnObject.clear();
          5. this->m_returnObject.unite(object);
          6. QString addedBonus = QString::number(object["intValue"].toInt(),
          7. 10).append(" added bonus.");
          8. this->m_returnObject["stringValue"] = QVariant(addedBonus);
          9. qDebug() << "SampleQObject::slotThatReturns" << this->m_returnObject;
          10. return this->m_returnObject; // 返回m_returnObject包含有字符串 1 added bonus
          11. }
    3. Run the app

 

Picture11.png

 

本例子代碼下載地址: http://software.intel.com/file/28111 http://software.intel.com/file/28112
注:本例子中部分代碼來自wiki.forum.nokia.com
http://wiki.forum.nokia.com/index.php/Exposing_QObjects_to_Qt_Webkit
下一篇我們將探索一下如何將S60下的web runtime widget porting至Qt的webkit上來,如今的WRT widget只能依賴於S60的os,如果porting只QT的webkit,那麼將可以實現廣泛開發者夢寐已久的跨平臺功能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章