QWebChannel实现QT与网页JS交互

qwebchannel.js是官方自动例子的js文件,可从Qt安装目录拷贝,存放于服务器或者本地

编程实例:

main.cpp 文件:

#include <QApplication>
#include "TMainWindow.h"

int main(int argc, char** argv)
{
    QApplication app(argc, argv);

    TMainWindow mainWindow;
    mainWindow.show();
    return app.exec();
}

TMainWindow.h 文件:

#ifndef TMAINWINDOW_H
#define TMAINWINDOW_H

#include <QDialog>

QT_BEGIN_NAMESPACE
class QPlainTextEdit;
class QLineEdit;
class QPushButton;
class QWebEngineView;
QT_END_NAMESPACE

class TMainWindow : public QDialog
{
    Q_OBJECT
public:
    TMainWindow(QDialog *parent = 0);
    ~TMainWindow();

    void OnReceiveMessageFromJS(QString strParameter);
    
signals:
    void SigSendMessageToJS(QString strParameter);

private:
    void OnSendMessageByInteractObj();
    void OnSendMessageByJavaScript();

    QPlainTextEdit *mpQtContentTextEdit;
    QLineEdit      *mpQtSendLineEdit;
    QPushButton    *mpQtSendBtnByInteractObj;
    QPushButton    *mpQtSendBtnByJavaScript;
    QWebEngineView *mpJSWebView;
};

#endif //TMAINWINDOW_H 

TMainWindow.cpp 文件:

#include "TMainWindow.h"
#include "TInteractObject.h"

#include <QPlainTextEdit>
#include <QLineEdit>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGroupBox>
#include <QWebChannel>
#include <QWebEngineView>
#include <QFileInfo>

TMainWindow::TMainWindow(QDialog *parent)
: QDialog(parent)
{
    //---Qt widget and layout---
    mpQtContentTextEdit = new QPlainTextEdit(this);
    mpQtContentTextEdit->setMidLineWidth(400);
    mpQtContentTextEdit->setReadOnly(true);

    mpQtSendLineEdit = new QLineEdit(this);
    mpQtSendBtnByInteractObj = new QPushButton("Send", this);
    mpQtSendBtnByInteractObj->setToolTip(tr("Send message by Interact object style"));

    mpQtSendBtnByJavaScript  = new QPushButton("Send2", this);
    mpQtSendBtnByJavaScript->setToolTip(tr("Send message by runJavaScript style"));

    QHBoxLayout *pQtSendHLayout = new QHBoxLayout;
    pQtSendHLayout->setMargin(0);
    pQtSendHLayout->setSpacing(0);
    pQtSendHLayout->addWidget(mpQtSendLineEdit);
    pQtSendHLayout->addSpacing(5);
    pQtSendHLayout->addWidget(mpQtSendBtnByInteractObj);
    pQtSendHLayout->addSpacing(5);
    pQtSendHLayout->addWidget(mpQtSendBtnByJavaScript);

    QVBoxLayout *pQtTotalVLayout = new QVBoxLayout;
    pQtTotalVLayout->setMargin(5);
    pQtTotalVLayout->setSpacing(0);
    pQtTotalVLayout->addWidget(mpQtContentTextEdit);
    pQtTotalVLayout->addSpacing(5);
    pQtTotalVLayout->addLayout(pQtSendHLayout);

    QGroupBox *pQtGroup = new QGroupBox("Qt View", this);
    pQtGroup->setLayout(pQtTotalVLayout);

    //---Web widget and layout---
    mpJSWebView = new QWebEngineView(this);                                 //创建一个网页视图对象

    QWebChannel *pWebChannel   = new QWebChannel(mpJSWebView->page());      //为网页视图页面创建通道channel 
    TInteractObj *pInteractObj = new TInteractObj(this);                    //创建通道对象用于与JS交互
    //"interactObj"为注册名,JS调用的对象名必须和它相同
    pWebChannel->registerObject(QStringLiteral("interactObj"), pInteractObj);//注册通道对象供JS调用   

    mpJSWebView->page()->setWebChannel(pWebChannel);                         //设置通道
    mpJSWebView->page()->load(QUrl::fromLocalFile(QFileInfo("./JSTest.html").absoluteFilePath()));
    mpJSWebView->show();

    QVBoxLayout *pJSTotalVLayout = new QVBoxLayout();
    pJSTotalVLayout->setMargin(0);
    pJSTotalVLayout->setSpacing(0);
    pJSTotalVLayout->addWidget(mpJSWebView);

    QGroupBox *pWebGroup = new QGroupBox("Web View", this);
    pWebGroup->setLayout(pJSTotalVLayout);

    //---TMainWindow total layout---
    QHBoxLayout *mainLayout = new QHBoxLayout;
    mainLayout->setMargin(5);
    mainLayout->setSpacing(0);
    mainLayout->addWidget(pQtGroup);
    mainLayout->addSpacing(5);
    mainLayout->addWidget(pWebGroup);
    setLayout(mainLayout);
    this->setMinimumSize(800, 600);

    //消息来源于消息响应的链接
    connect(mpQtSendBtnByInteractObj, &QPushButton::clicked,this,&TMainWindow::OnSendMessageByInteractObj);
    connect(mpQtSendBtnByJavaScript,  &QPushButton::clicked,this,&TMainWindow::OnSendMessageByJavaScript);
    connect(pInteractObj, &TInteractObj::SigReceivedMessFromJS, this,&TMainWindow::OnReceiveMessageFromJS);
    connect(this, &TMainWindow::SigSendMessageToJS,pInteractObj, &TInteractObj::SigSendMessageToJS);
}

TMainWindow::~TMainWindow()
{
}

void TMainWindow::OnReceiveMessageFromJS(QString strParameter)
{
    if (strParameter.isEmpty()){
        return;
    }

    mpQtContentTextEdit->appendPlainText(strParameter);
}

void TMainWindow::OnSendMessageByInteractObj()
{
    QString strMessage = mpQtSendLineEdit->text().trimmed();
    if (strMessage.isEmpty()){
        return;
    }

    emit SigSendMessageToJS(strMessage);
}

void TMainWindow::OnSendMessageByJavaScript()
{
    QString strMessage = mpQtSendLineEdit->text().trimmed();
    if (strMessage.isEmpty()){
        return;
    }

    strMessage = QString("Received string from Qt: %1").arg(strMessage);
    mpJSWebView->page()->runJavaScript(QString("output('%1');").arg(strMessage));
}

TInteractObject.h 文件:

#ifndef TINTERACT_OBJECT_H
#define TINTERACT_OBJECT_H
#include <QObject>

class TInteractObj : public QObject
{
    Q_OBJECT
public:
    TInteractObj(QObject *parent);
    ~TInteractObj();
    //页面端调用QT公共接口,必须有Q_INVOKABLE
    Q_INVOKABLE void JSSendMessage(QString strParameter);       //Called by JS: Send message to Qt

signals:
    void SigReceivedMessFromJS(QString strParameter);          //Receive message from Web
    void SigSendMessageToJS(QString strParameter);             //Send message to Web
};

#endif //TINTERACT_OBJECT_H 

TInteractObject.cpp 文件:

#include "TInteractObject.h"

TInteractObj::TInteractObj(QObject *parent)
    :QObject(parent)
{
}

TInteractObj::~TInteractObj()
{
}

void TInteractObj::JSSendMessage(QString strParameter)
{
    emit SigReceivedMessFromJS(strParameter);
}

页面端模拟文件JSTest.html

<!DOCTYPE html>  
<html>  
    <head>  
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
        <script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script>  
        <script type="text/javascript">  
        //---Web show receive message---
        function output(message)  
        {  
            var output = document.getElementById("output");  
            output.innerHTML = output.innerHTML + message + "\n";  
        }  
        
        //Web initial loading 
         window.onload = function() {  
            output("");  
            new QWebChannel(qt.webChannelTransport, function(channel) {    //浏览器内核自带
            
                //Get Qt interact object  
                var interactObj = channel.objects.interactObj;      //注册对象名
                
                //Web send message to Qt 
                document.getElementById("send").onclick = function() {  
                    var input = document.getElementById("input");  
                    if (!input.value) {  
                        return;  
                    }  
                    
                    //Web use the interface of Qt 
                    interactObj.JSSendMessage(input.value);           //发送消息
                    input.value = "";                      
                }  
                
                //Web connect the Qt signal, then Qt can call "output" function
                interactObj.SigSendMessageToJS.connect(function(str) {       //接收信号,响应函数
                    output("Received string from Qt: " + str);  
                });    
            });  
            }  
  
        </script>  
        <style type="text/css">  
            html {  
                height: 100%;  
                width: 100%;  
            }  
            #input {  
                width: 650px;  
                margin: 0 10px 0 0;  
            }  
            #send {  
                width: 90px;  
                margin: 0;  
            }  
            #output {  
                width: 770px;  
                height: 550px;  
            }  
        </style>  
    </head>  
    <body>  
        <textarea id="output" readonly="readonly"></textarea><br />  
        <input id="input" />  
        <input type="submit" id="send" value="Send" onclick="javascript:click();" />  
    </body>  
</html>  


运行效果

Qt界面Send按钮通过QtWebChannel绑定对象,向Web页面端发送消息("Hello JavaScript");
Qt界面Send2按钮通过runJavaScript调用页面端公共接口,向Web页面端发送消息("Hello JavaScript");
Web页面端Send按钮通过关联Qt界面公共接口,向Qt端发送消息("Hello Qt");

展开阅读全文

没有更多推荐了,返回首页