轉自:
一、 簡介
Qt提供了本地C++對象與JavaScript的無縫集成,可以進行本地與web混合應用開發。利用Qt的Webkit集成與QtNetwork模塊,可以自由的混合JavaScript、樣式表、Web內容和Qt組件。對於C++和javaScript通信,最基本也最復雜的做法是使用COM,本文主要介紹使用Qt提供的QWebView和javaScript進行通信。
二、 流程
基本函數介紹
Qt與JavaScript互調是通過QWebFrame兩個函數來實現的:addToJavaScriptWindowObject()將QObject對象傳給JS,這樣JS就能調用QObject的共有槽函數。Qt通過evaluateJavaScript()直接調用JS中德函數。其流程如下圖:
函數說明
1. void QWebFrame::addToJavaScriptWindowObject(const QString& name, QObject * object) 第一個參數:name為對象在javaScript里的名字,可以自由命名。 第二個參數:object對應的QObject實例指針。 要在JS調用該QObject之前調用這個函數,建議將這個函數放到一個signal的槽函數中調用,其使用代碼代碼如下: connect(ui.webView->page()->mainFrame(),SIGNAL(javaScriptWindowObjectCleared()),this, SLOT(populateJavaScriptWindowObject())); 相應的槽函數為: void 類名::populateJavaScriptWindowObject() { ui.webView->page()->mainFrame()->addToJavaScriptWindowObject(“formExtractor”, this); } 2. QVariant QWebFrame::evaluateJavaScript(const QString &scriptSource) 建立一個工程,拖入一個QWebView,載入html網頁,添加一個按鈕調用javaScript,其代碼為: Ui.webView->page()->mainframe()->evaluateJavaScript(“Test()”) ; 其中Test()為javaScript中的Test()函數。 附注:如果Qt調用js函數,js函數帶有參數,在Qt里該函數調用方法要寫成如下形式: QString method = QString(“JSFunction(\”%1\” , \”%2\”)”).arg(param1).arg(param2) ; Ui.webView->page()->mainframe()->evaluateJavaScript(method) ; 三、 工程示例 新建Qt GUI工程項目QtJS,類名為mainWindow,繼承基類選擇為QMainWindow。往ui里拖入控件,其布局按如下設置:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
在mainwindow.cpp中添加頭文件#include <QtCore/QUrl>、#include<QtWebK itWidgets/QWebView>、#include <QtWebKitWidgets/QWebFrame>、#include<QtW ebkit/QWebElement>。在mainwindow.h頭文件中添加公有槽函數 void populateJavaScriptWindowObject() ;//為了保證每次打開新網頁或刷新網頁時都調用,將該槽函數和javaScriptWindowObjectCleared()信號相連 void pop1() ; //不傳遞參數到JavaScript void pop2() ;//將Qt中的值傳遞到JavaScript void JsCallQt() ;//JavaScript調用Qt,不傳遞參數 void JsCallQt(QStringList str) ;//JavaScript調用Qt,傳遞參數 在構造函數中建立信號和槽的連接 connect(ui.pushButton , SIGNAL(clicked()) , this , SLOT(pop1())) ; connect(ui.pushButton_2 , SIGNAL(clicked()) , this , SLOT(pop2())) ; connect(ui.webView->page()->mainFrame() , SIGNAL(javaScriptWindow -ObjectCleared()) , this , SLOT(populateJavaScriptWindowObject())) ; 分別添加槽函數的定義: void mainWindow::populateJavaScriptWindowObject() { ui.webView->page()->mainFrame()->addToJavaScriptWindowObject("A" , this) ; } 單擊按鈕(“不帶參數傳遞到JS”),其效果如下圖:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
彈出對話框為html中的一個警告,其代碼如下:
在文本框中輸入X、Y的值,單擊按鈕(“帶參數傳遞到JS”),其效果
通過JavaScript調用Qt主要有兩種方式,第一種:在Qt中定義一個公有的槽函數;第二種:在公有成員函數前添加Q_INVOKABLE宏。
添加JsCallQt()的定義如下:
void mainWindow::JsCallQt(QStringList str)
{
ui.lineEdit_3->setText(str[0]) ; ui.lineEdit_4->setText(str[1]) ; } void mainWindow::JsCallQt() { QWebFrame *frame = ui.webView->page()->mainFrame(); QWebElement X = frame->findFirstElement("#X"); ui.lineEdit_3->setText(X.evaluateJavaScript("this.value").toString()) ; QWebElement Y = frame->findFirstElement("#Y"); ui.lineEdit_4->setText(Y.evaluateJavaScript("this.value").toString()) ; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
JsCallQt()的兩個版本分別對應html中的兩個按鈕,推薦使用第二種方式。第一種帶參數傳遞時,好像需要在javascript中將變量設置為數組,傳遞多個參數時好像會失效(有興趣可以驗證)。
單擊html中的按鈕(“第二種方式傳遞到Qt”),其顯示效果如下圖:
一、 簡介
Qt提供了本地C++對象與JavaScript的無縫集成,可以進行本地與web混合應用開發。利用Qt的Webkit集成與QtNetwork模塊,可以自由的混合JavaScript、樣式表、Web內容和Qt組件。對於C++和javaScript通信,最基本也最復雜的做法是使用COM,本文主要介紹使用Qt提供的QWebView和javaScript進行通信。
二、 流程
基本函數介紹
Qt與JavaScript互調是通過QWebFrame兩個函數來實現的:addToJavaScriptWindowObject()將QObject對象傳給JS,這樣JS就能調用QObject的共有槽函數。Qt通過evaluateJavaScript()直接調用JS中德函數。其流程如下圖:
函數說明
1. void QWebFrame::addToJavaScriptWindowObject(const QString& name, QObject * object) 第一個參數:name為對象在javaScript里的名字,可以自由命名。 第二個參數:object對應的QObject實例指針。 要在JS調用該QObject之前調用這個函數,建議將這個函數放到一個signal的槽函數中調用,其使用代碼代碼如下: connect(ui.webView->page()->mainFrame(),SIGNAL(javaScriptWindowObjectCleared()),this, SLOT(populateJavaScriptWindowObject())); 相應的槽函數為: void 類名::populateJavaScriptWindowObject() { ui.webView->page()->mainFrame()->addToJavaScriptWindowObject(“formExtractor”, this); } 2. QVariant QWebFrame::evaluateJavaScript(const QString &scriptSource) 建立一個工程,拖入一個QWebView,載入html網頁,添加一個按鈕調用javaScript,其代碼為: Ui.webView->page()->mainframe()->evaluateJavaScript(“Test()”) ; 其中Test()為javaScript中的Test()函數。 附注:如果Qt調用js函數,js函數帶有參數,在Qt里該函數調用方法要寫成如下形式: QString method = QString(“JSFunction(\”%1\” , \”%2\”)”).arg(param1).arg(param2) ; Ui.webView->page()->mainframe()->evaluateJavaScript(method) ; 三、 工程示例 新建Qt GUI工程項目QtJS,類名為mainWindow,繼承基類選擇為QMainWindow。往ui里拖入控件,其布局按如下設置:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
在mainwindow.cpp中添加頭文件#include <QtCore/QUrl>、#include<QtWebK itWidgets/QWebView>、#include <QtWebKitWidgets/QWebFrame>、#include<QtW ebkit/QWebElement>。在mainwindow.h頭文件中添加公有槽函數 void populateJavaScriptWindowObject() ;//為了保證每次打開新網頁或刷新網頁時都調用,將該槽函數和javaScriptWindowObjectCleared()信號相連 void pop1() ; //不傳遞參數到JavaScript void pop2() ;//將Qt中的值傳遞到JavaScript void JsCallQt() ;//JavaScript調用Qt,不傳遞參數 void JsCallQt(QStringList str) ;//JavaScript調用Qt,傳遞參數 在構造函數中建立信號和槽的連接 connect(ui.pushButton , SIGNAL(clicked()) , this , SLOT(pop1())) ; connect(ui.pushButton_2 , SIGNAL(clicked()) , this , SLOT(pop2())) ; connect(ui.webView->page()->mainFrame() , SIGNAL(javaScriptWindow -ObjectCleared()) , this , SLOT(populateJavaScriptWindowObject())) ; 分別添加槽函數的定義: void mainWindow::populateJavaScriptWindowObject() { ui.webView->page()->mainFrame()->addToJavaScriptWindowObject("A" , this) ; } 單擊按鈕(“不帶參數傳遞到JS”),其效果如下圖:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
彈出對話框為html中的一個警告,其代碼如下:
在文本框中輸入X、Y的值,單擊按鈕(“帶參數傳遞到JS”),其效果
通過JavaScript調用Qt主要有兩種方式,第一種:在Qt中定義一個公有的槽函數;第二種:在公有成員函數前添加Q_INVOKABLE宏。
添加JsCallQt()的定義如下:
void mainWindow::JsCallQt(QStringList str)
{
ui.lineEdit_3->setText(str[0]) ; ui.lineEdit_4->setText(str[1]) ; } void mainWindow::JsCallQt() { QWebFrame *frame = ui.webView->page()->mainFrame(); QWebElement X = frame->findFirstElement("#X"); ui.lineEdit_3->setText(X.evaluateJavaScript("this.value").toString()) ; QWebElement Y = frame->findFirstElement("#Y"); ui.lineEdit_4->setText(Y.evaluateJavaScript("this.value").toString()) ; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
JsCallQt()的兩個版本分別對應html中的兩個按鈕,推薦使用第二種方式。第一種帶參數傳遞時,好像需要在javascript中將變量設置為數組,傳遞多個參數時好像會失效(有興趣可以驗證)。
單擊html中的按鈕(“第二種方式傳遞到Qt”),其顯示效果如下圖: