QT+HTML+JS混合编程(QT5.9+QWebEngineView +QWebchannel)

被HTML优雅界面吸引,初次学习QT+html混合编程开发,参考了https://blog.csdn.net/Best_ZYJ/article/details/79027245。以下是简单的登陆界面开发步骤,附源码。

QT:

  1. 工程文件.pro添加:

Webenginewidgets (web显示类,用于显示web界面)

Webchannel(web数据通道类,用于数据通信)

 

QT       += core gui webenginewidgets webchannel

 

  1. 创建通道对象类(qt与web通信是通过对象的方式交换数据)

创建类TinteractObj

        
class TInteractObj : public QObject
{

    Q_OBJECT

public:

    TInteractObj(QObject *parent);

    ~TInteractObj();

    //页面端调用QT公共接口,必须有Q_INVOKABLE

    //页面端调用QT变量,用Q_PROPERTY,用法与QML相同

    Q_INVOKABLE void JSSendMessage(QString strParameter,QString str);

    Q_PROPERTY(QString username READ username WRITE setusername NOTIFY sig_nameChanged)

    Q_PROPERTY(QString password READ password WRITE setpassword NOTIFY sig_passwdChanged)



    QString m_username;    //本地保存的数据对象

    QString m_password;       



    QString username(){

        return m_username;

    }

    QString password(){

        return m_password;

    }

    void setusername(QString str){

        m_username = str;

    }

    void setpassword(QString str){

        m_password = str;

    }





signals:

    void sig_nameChanged();

    void sig_passwdChanged();

    void SigReceivedMessFromJS(QString strParameter,QString str);          //网页调用函数给qt发送该信号

    void SigSendMessageToJS(QString strParameter);             //给网页发送数据的信号



};

3、在主类中添加私有对象:

    QWebEngineView *webview;     //网页显示类对象,QT5.5之前使用的是QWebkit

    TInteractObj *pInteractObj;       //与网页数据交换类对象

4、类构造函数添加

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

    webview->page()->setWebChannel(pWebChannel);                         //设置通道

    QString strfile = QCoreApplication::applicationDirPath();
//导入本地html文件    webview->page()->load( QUrl("file:///"+strfile+"/index.html"));
//当网页返回数据,则会返回到通道对象pInteractObj中,然后再发送信号到主类OnReceiveMessageFromJS中处理
connect(pInteractObj, &TInteractObj::SigReceivedMessFromJS, this,&Widget::OnReceiveMessageFromJS);
//向网页发送信号需要利用通道对象pInteractObj的SigSendMessageToJS信号
    connect(this,&Widget::SigSendMessageToJS,pInteractObj, &TInteractObj::SigSendMessageToJS);

html中写js交互函数

注意:无以下这句会无法创建QwebChannel对象,qwebchannel.js可在QT安装目录下查找,然后修改src路径即可

       <script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script>

       <script src="vendor/jquery/jquery-3.2.1.min.js"></script>

       <script type="text/javascript">

       window.onload = function() { 

            new QWebChannel(qt.webChannelTransport, function(channel) {    //浏览器内核自带,创建通道对象   

                var interactObj = channel.objects.interactObj;      //注册对象名需要对应QT中

                            $("#_login_").click(function(){        //发送消息给QT

                                    var name = document.getElementById("_username_").value;

                                    var passwd = document.getElementById("_password_").value;

                                    interactObj.JSSendMessage(name,passwd);          

                            })

                interactObj.SigSendMessageToJS.connect(function(str) {       //接收信号,响应函数

                    if(str == "ok")

                                          alert("success");

                });   

            }); 

            }  

       </script> 

 

 

—————————————————————————————————————————————————

—————————————————————分割线—————————————————————————

以下是源码:

qtforhtml_login.pro

#-------------------------------------------------
#
# Project created by QtCreator 2018-12-26T16:16:25
#
#-------------------------------------------------

QT       += core gui webenginewidgets webchannel

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = qtforhtml_login
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0


SOURCES += main.cpp\
        widget.cpp \
    tinteractobj.cpp

HEADERS  += widget.h \
    tinteractobj.h

FORMS    += widget.ui

tinteractobj.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
    //页面端调用QT变量,用Q_PROPERTY,用法与QML相同
    Q_INVOKABLE void JSSendMessage(QString strParameter,QString str);
    Q_PROPERTY(QString username READ username WRITE setusername NOTIFY sig_nameChanged)
    Q_PROPERTY(QString password READ password WRITE setpassword NOTIFY sig_passwdChanged)

    QString m_username;
    QString m_password;

    QString username(){
        return m_username;
    }
    QString password(){
        return m_password;
    }
    void setusername(QString str){
        m_username = str;
    }
    void setpassword(QString str){
        m_password = str;
    }


signals:
    void sig_nameChanged();
    void sig_passwdChanged();
    void SigReceivedMessFromJS(QString strParameter,QString str);          //Receive message from Web
    void SigSendMessageToJS(QString strParameter);             //Send message to Web

};

#endif //TINTERACT_OBJECT_H

tinteractobj.cpp

#include "tinteractobj.h"

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

TInteractObj::~TInteractObj()
{
}

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

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QWebChannel>
#include <QWebEngineView>
#include "tinteractobj.h"
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

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

signals:
        void SigSendMessageToJS(QString strParameter);

public slots:
        void OnReceiveMessageFromJS(QString usr,QString passwd);
        void resizeEvent(QResizeEvent * event);
private:
    Ui::Widget *ui;

    QWebEngineView *webview;
    TInteractObj *pInteractObj;
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    webview = new QWebEngineView(this);
    webview->resize(this->size());
    QWebChannel *pWebChannel   = new QWebChannel(webview->page());      //为网页视图页面创建通道channel
    pInteractObj = new TInteractObj(this);                   //创建通道对象用于与JS交互
    //"interactObj"为注册名,JS调用的对象名必须和它相同
    pWebChannel->registerObject(QStringLiteral("interactObj"), pInteractObj);//注册通道对象供JS调用

    webview->page()->setWebChannel(pWebChannel);                         //设置通道

    QString strfile = QCoreApplication::applicationDirPath();
    webview->page()->load( QUrl("file:///"+strfile+"/index.html"));

    connect(pInteractObj, &TInteractObj::SigReceivedMessFromJS, this,&Widget::OnReceiveMessageFromJS);
    connect(this, &Widget::SigSendMessageToJS,pInteractObj, &TInteractObj::SigSendMessageToJS);
}
void Widget::OnReceiveMessageFromJS(QString usr,QString passwd)
{
    qDebug()<<"QDebug"<<usr<<passwd;
    emit SigSendMessageToJS("ok");
}
Widget::~Widget()
{
    delete ui;
}
void Widget::resizeEvent(QResizeEvent * event){
   webview->resize(this->size());
}

index.html

<!DOCTYPE html>
<html lang="zh-CN">

<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	
	<title>HTML5+QT</title>
	<meta name="keywords" content="" />
	<meta name="description" content="" /> 
</head>

<body>

	<div class="limiter">
		<div class="container-login100" style="background-image: url('images/bg-01.jpg');">
			<div class="wrap-login100 p-l-55 p-r-55 p-t-65 p-b-54">
				<form class="login100-form validate-form">
					<span class="login100-form-title p-b-49">登录</span>

					<div class="wrap-input100 validate-input m-b-23" data-validate="请输入用户名">
						<span class="label-input100">用户名</span>
						<input class="input100" type="text" name="username" placeholder="请输入用户名" autocomplete="off" id = "_username_">
						<span class="focus-input100" data-symbol="&#xf206;"></span>
					</div>

					<div class="wrap-input100 validate-input" data-validate="请输入密码">
						<span class="label-input100">密码</span>
						<input class="input100" type="password" name="pass" placeholder="请输入密码" id = "_password_">
						<span class="focus-input100" data-symbol="&#xf190;"></span>
					</div>

					<div class="text-right p-t-8 p-b-31">
						<a href="javascript:">忘记密码?</a>
					</div>

					<div class="container-login100-form-btn">
						<div class="wrap-login100-form-btn">
							<div class="login100-form-bgbtn"></div>
							<button class="login100-form-btn" id = "_login_">登 录</button>
						</div>
					</div>

					<div class="txt1 text-center p-t-54 p-b-20">
						<span>第三方登录</span>
					</div>

					<div class="flex-c-m">
						<a href="#" class="login100-social-item bg1">
							<i class="fa fa-wechat"></i>
						</a>

						<a href="#" class="login100-social-item bg2">
							<i class="fa fa-qq"></i>
						</a>

						<a href="#" class="login100-social-item bg3">
							<i class="fa fa-weibo"></i>
						</a>
					</div>

					<div class="flex-col-c p-t-25">
						<a href="javascript:" class="txt2">立即注册</a>
					</div>
				</form>
			</div>
		</div>
	</div>
	<script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script>
	<script src="vendor/jquery/jquery-3.2.1.min.js"></script>
	<!--<script src="js/main.js"></script>-->
	<script type="text/javascript"> 
	window.onload = function() {  
            new QWebChannel(qt.webChannelTransport, function(channel) {    //浏览器内核自带
			
                //Get Qt interact object  
                var interactObj = channel.objects.interactObj;      //注册对象名
                
                //Web send message to Qt 
				$("#_login_").click(function(){
					 
					 var name = document.getElementById("_username_").value;
					 var passwd = document.getElementById("_password_").value;

						 interactObj.JSSendMessage(name,passwd);           //发送消息
				})
                //Web connect the Qt signal, then Qt can call "output" function
                interactObj.SigSendMessageToJS.connect(function(str) {       //接收信号,响应函数
                    if(str == "ok")
						alert("success");
                });    
            });  
            }  



	 </script>  
</body>

</html>

注意:qwebchannel.js可在QT安装目录下查找

展开阅读全文

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