被HTML优雅界面吸引,初次学习QT+html混合编程开发,参考了https://blog.csdn.net/Best_ZYJ/article/details/79027245。以下是简单的登陆界面开发步骤,附源码。
QT:
- 工程文件.pro添加:
Webenginewidgets (web显示类,用于显示web界面)
Webchannel(web数据通道类,用于数据通信)
QT += core gui webenginewidgets webchannel
- 创建通道对象类(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=""></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=""></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安装目录下查找