Qt與Javascript的通信機制

寫在前面

  1. Qt的一些基本用法可自行百度,也可以系統地學習一下QT學習之路,就喜歡這種江湖老師,無比感謝~
  2. 本文也參考了一些博客,加上我自己的理解之后整理得到。原理就不細講了,重點講用法。
  3. 本文也會涉及一點非常非常簡單的javasript語法,可以速成,參考w3school,有好的編程基礎的話,入門是可以秒殺的。

QT

順序有點亂

  1. 先新建一個工程,搭好一個UI(最簡陋的)


    一個PushButton和一個webView

    名字可自取,但為了方便演示,就采用默認的。Layout不會的話可以不用。

  2. 添加槽函數


    單擊PushButton->轉到槽

    會自動幫你申明函數和鏈接(connect),你只需要在相應的函數體內添加內容即可,之后在講這個。

  3. 手動添加代碼
  • mainwindow.h中添加void slotPopulateJavaScriptWindowObject()
#include <QWebView>
#include <QtWebKit>
#include <QWebFrame>
#include <QMainWindow>
#include <QMessageBox>
#include <QString>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:

    void slotPopulateJavaScriptWindowObject();

    void on_pushButton_clicked();       //自動生成

private:
    Ui::MainWindow *ui;
};

  • 具體實現,將以下代碼加入到MainWindow.cpp
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setWindowTitle(tr("演示"));


    QString strMapPath="file:///";                              //exe文件所在的絕對路徑
    strMapPath+=QCoreApplication::applicationDirPath();
    strMapPath+="/yanshi.html";
    QUrl url(strMapPath);       //注意是絕對路徑
    ui->webView->load(url);     //打開本地的.html文件
    //當然也可以把html放在任何地方,能保證計算機找得到就行
    connect(ui->webView->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()),
            this, SLOT(slotPopulateJavaScriptWindowObject()));  //將Qt與js聯系起來
    //收到mainFrame()發出的SIGNAL后,this調用slotPopulateJavaScriptWindowObject
    //QT與JavaScript互調是通過QWebFrame的兩個函數來實現的:
    //addToJavaScriptWindowObject()將QObject對象傳給JS,這樣JS就能調用QObject的public slots函數
    //QT通過evaluateJavaScript()直接調用JS中的函數
}


MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::slotPopulateJavaScriptWindowObject()
{
    ui->webView->page()->mainFrame()->addToJavaScriptWindowObject("ReinforcePC", this);
    //addToJavaScriptWindowObject()將QObject對象傳給JS,這樣JS就能調用QObject的public slots函數
    //addToJavaScriptWindowObject的第一個參數是對象在javascript里的名字, 可以自由命名, 第二個參數是對應的QObject實例指針。
}

void MainWindow::on_pushButton_clicked()
{
    QWebFrame *webFrame = ui->webView->page()->mainFrame();
    QString cmd = QString("showhello()");
    webFrame->evaluateJavaScript(cmd);      //QT通過evaluateJavaScript()直接調用JS中的函數
}

html

新建一個html文件,代碼如下:

<!DOCTYPE html>
<html>
<body>


<script>
function showhello()
{
    alert("Welcome, newbird "); //這是一個很簡單的無參的函數
}
</script>

</body>
</html>

解釋及效果

  1. 代碼中的注釋大致已經講清楚了用法,再來系統的講一遍。
    首先,JS調用QT中的函數,看這個:
connect(ui->webView->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()),
        this, SLOT(slotPopulateJavaScriptWindowObject()));  //將Qt與js聯系起來

其中,第一個參數ui->webView->page()->mainFrame()是信號的發送方,是QwebView里面的一個東東,它發出javaScriptWindowObjectCleared()信號,這個信號的具體形式你可以不管,就像pushbuttonclick()信號,都是已經寫好的。第三個參數是this,一個指針。第四個參數是slotPopulateJavaScriptWindowObject()函數。這條語句的意思就是:在收到mainFrame()發出的SIGNAL后,this調用slotPopulateJavaScriptWindowObject實現相應的操作或者功能,而這個功能就是 將QObject對象傳給JS,這樣JS就能調用QObjectpublic slots函數,就如同使用自己的function一樣。
其次,QT調用JS中的函數:

QWebFrame *webFrame = ui->webView->page()->mainFrame();
QString cmd = QString("showhello()");
webFrame->evaluateJavaScript(cmd);

意思就是,一個QwebFrame指針可以通過evaluateJavaScript函數把命令傳遞過去,在以上的代碼中這個命令就是showhello(),這個就是js中的一個函數。仿佛是在直接調用qt中的函數。

  1. 效果
  • QTJS的調用

運行之后如圖,因為網頁沒寫什么所以是空白的

單擊pushbutton,會執行on_pushButton_clicked()函數,因為你在執行轉到槽的過程中,系統已經自動幫你connect好了,顯示如下
js的alert語句執行了

由此可見,好像是pushbutton直接調用了JS中的showhello()函數。

  • JSQT的調用
    需要將代碼做如下修改
    a. yanshi.html
<!DOCTYPE html>
<html>
<body>


<button onclick="showhello()">here</button>
<script>
function showhello()
{
    //alert("Welcome, newbird ");
    var string= "hello oldbird";
    ReinforcePC.showinfo(string);//調用qt中的showinfo()函數
}
</script>

</body>
</html>

b. MainWindow.h

#include <QWebView>
#include <QtWebKit>
#include <QWebFrame>
#include <QMainWindow>
#include <QMessageBox>
#include <QString>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:

    void slotPopulateJavaScriptWindowObject();

    void on_pushButton_clicked();       //自動生成
public slots:

    void showinfo(QString string);        //注意是在public slots中

private:
    Ui::MainWindow *ui;
};

c. MainWindow.cpp
添加以下函數即可

void MainWindow::showinfo(QString string)
{
    QMessageBox::information(this,tr("消息"),string); //彈出消息框
}

d. 效果

運行之后
點擊here之后

由此可見,好像是JS中的showhello()直接調用了QT中的showinfo()函數,實現這個的就是之前講的

connect(ui->webView->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()),
        this, SLOT(slotPopulateJavaScriptWindowObject()));  //將Qt與js聯系起來

總結

至此,你已經能夠讓Qtjavascript互相打電話啦,開心不。
哦,對了,還有一個傳參數的問題,qt給js傳參的話可以這樣寫,上面是沒有參數的。只能是字符串形式

QString cmd = QString("showtrace(\"%1\",\"%2\")").arg(lonJson).arg(latJson);

可能有不正確的地方,請諒解
碼字不易,轉載請注明地址

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 為什么在頭文件中有的是使用前置聲明,而有的是包含頭文件? 如下代碼: 前置聲明(forward declarati...
    Joe_HUST閱讀 1,324評論 0 6
  • 一、溫故而知新 1. 內存不夠怎么辦 內存簡單分配策略的問題地址空間不隔離內存使用效率低程序運行的地址不確定 關于...
    SeanCST閱讀 7,880評論 0 27
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,377評論 25 708
  • 轉自:作者簡介作者:唐新華 (xhsmart@263.net)軟件工程師 ?? 信號和槽作為QT的核心機制在QT編...
    njukay閱讀 1,359評論 0 49
  • 1.出現爭辯時,把對方逼上絕路; 2.過于賣弄自己; 3.喋喋不休發牢騷訴說自己的不幸; 4.在朋友痛苦無助時,談...
    蟹老闆閱讀 1,188評論 3 10