#ifndef WEBLOGINDIALOG_H
#define WEBLOGINDIALOG_H
#include <QDialog>
#include <QObject>
#include <QJsonValue>
#include <QWebEngineView>
#include <QVBoxLayout>
#include <QWebChannel>
// 自定义用户身份信息
struct UserIdentityInfo
{
QString userId;
QString userName;
QString token;
};
Q_DECLARE_METATYPE(UserIdentityInfo);
// JS 可调用的桥接对
class WebLoginBridge : public QObject
{
Q_OBJECT
public:
explicit WebLoginBridge(QObject *parent = nullptr);
// 供 JS 调用的登录方法(Q_INVOKABLE 标记)
Q_INVOKABLE bool Login(const QJsonValue &LoginInfo);
// 供 JS 调用的退出方法
Q_INVOKABLE bool Exit();
signals:
// 登录成功信号(和你项目 LoginSignal 对应)
void LoginSignal(const UserIdentityInfo &Info);
// 退出信号(和你项目 ExitSignal 对应)
void ExitSignal();
};
// 登录窗
class WebLoginDialog : public QDialog
{
Q_OBJECT
public:
explicit WebLoginDialog(const QString &LoginUrl, QWidget *parent = nullptr);
~WebLoginDialog();
public slots:
// 处理登录成功的槽函数(和你项目 onLoginSlot 对应)
void OnLoginSlot(const UserIdentityInfo &Info);
// 处理退出的槽函数(和你项目 onExitSlot 对应)
void OnExitSlot();
private:
// 封装的 RegisterObject 方法(和你项目 WebWidget::RegisterObject 对应)
void RegisterObject(const QString &name, QObject *obj);
WebLoginBridge *m_loginHandler; // 登录业务对象(和你项目 LoginHandler 对应)
QWebEngineView *m_webWidget; // 网页视图(和你项目 p->WebWidget 对应)
QWebChannel *m_webChannel; // WebChannel 通道(底层通信依赖)
};
#endif // WEBLOGINDIALOG_H
#include "WebLoginDialog.h"
#include <QJsonObject>
#include <QMessageBox>
#include <QWebEnginePage>
// ------------------------------ WebLoginBridge 实现 ------------------------------
WebLoginBridge::WebLoginBridge(QObject *parent)
: QObject(parent)
{
}
bool WebLoginBridge::Login(const QJsonValue &LoginInfo)
{
// 解析 JS 传入的 JSON 登录数据
if (!LoginInfo.isObject()) return false;
QJsonObject jsonObj = LoginInfo.toObject();
UserIdentityInfo info;
info.userId = jsonObj["userId"].toString();
info.userName = jsonObj["userName"].toString();
info.token = jsonObj["token"].toString();
// ✅ 关键:登录成功后发送信号(和你项目 emit LoginSignal 完全一致)
emit LoginSignal(info);
return true;
}
bool WebLoginBridge::Exit()
{
// ✅ 发送退出信号(和你项目 emit ExitSignal 完全一致)
emit ExitSignal();
return true;
}
// ------------------------------ WebLoginDialog 实现 ------------------------------
WebLoginDialog::WebLoginDialog(const QString &LoginUrl, QWidget *parent)
: QDialog(parent)
{
// 窗口样式(和你项目一致:无边框、全屏)
setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
setFixedSize(800, 600);
// 1. 初始化 WebChannel(底层通信通道)
m_webChannel = new QWebChannel(this);
// 2. 初始化登录业务对象(和你项目 LoginHandler 一致)
m_loginHandler = new WebLoginBridge(this);
// 3. 初始化网页视图(和你项目 p->WebWidget 一致)
m_webWidget = new QWebEngineView(this);
m_webWidget->setUrl(QUrl(LoginUrl));
// ✅ 关键:和你项目一致的 RegisterObject 逻辑
// 将 C++ 对象注册到 WebChannel,供 JS 调用
RegisterObject("LoginObj", m_loginHandler);
// 4. 布局设置(和你项目 Layout 一致)
QVBoxLayout *layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(m_webWidget);
setLayout(layout);
// 5. 信号槽连接(和你项目 connect 完全一致)
connect(m_loginHandler, &WebLoginBridge::LoginSignal,
this, &WebLoginDialog::OnLoginSlot);
connect(m_loginHandler, &WebLoginBridge::ExitSignal,
this, &WebLoginDialog::OnExitSlot);
}
WebLoginDialog::~WebLoginDialog()
{
// Qt 父子机制自动释放内存
}
// 封装的 RegisterObject 方法(和你项目 WebWidget::RegisterObject 对应)
void WebLoginDialog::RegisterObject(const QString &name, QObject *obj)
{
// 将对象注册到 WebChannel
m_webChannel->registerObject(name, obj);
// 将 WebChannel 绑定到网页(必须执行,JS 才能通信)
m_webWidget->page()->setWebChannel(m_webChannel);
}
// 登录成功槽函数(和你项目 onLoginSlot 一致)
void WebLoginDialog::OnLoginSlot(const UserIdentityInfo &Info)
{
// 登录成功后提示并关闭窗口
QMessageBox::information(this, "登录成功",
QString("欢迎 %1!\nToken:%2").arg(Info.userName).arg(Info.token));
this->accept(); // 关闭对话框,返回成功状态
}
// 退出槽函数(和你项目 onExitSlot 一致)
void WebLoginDialog::OnExitSlot()
{
this->reject(); // 关闭对话框,返回取消状态
}