【QT进阶】Qt http编程之用户登录注册功能实现

往期回顾

【QT进阶】Qt http编程之http与https简单介绍-CSDN博客

【QT进阶】Qt http编程之后端API测试工具postman使用介绍-CSDN博客

【QT进阶】Qt http编程之http相关类的简单介绍-CSDN博客

【QT进阶】Qt http编程之用户登录注册功能实现

一、最终效果展示

重点在逻辑实现,界面美化就先没弄

由于我没有启动相应接口,所以肯定是拿不到数据的,点击登录的结果就是请求超时,如果做了接口能拿到,就是直接展示获取的json格式数据

二、后端逻辑实现

主要是看看如何使用 Qt 的网络模块发送 HTTP POST请求,并添加超时处理的逻辑,以确保及时处理网络请求的超时情况。

1、思路

整体思路很清晰:点击登录按钮后执行槽函数,槽函数里执行发送http、post请求的函数,在该函数里设置各类需要的信息并发送post请求,然后调用函数执行post请求完成后的响应,获取请求状态码看是成功了还是失败了,弹出对应消息提示框即可

2、具体实现分析

2.1点击登录按钮后执行槽函数

点击登录按钮后执行槽函数,槽函数里执行发送http、post请求的函数,这里写了两个函数,考虑到的是是否超时,超时就执行另一个函数处理

//处理登录按钮点击事件
void login_register::on_btnLogin_clicked() 
{
    //执行发送 HTTP POST 请求的函数
    //test_http_post();  //发送 HTTP POST 请求
    test_timeout_http_post();  //发送 HTTP POST 超时请求
}
2.2设置信息执行post请求和响应

在发送http、post请求的函数里设置各类需要的信息并发送post请求,然后调用函数执行post请求完成后的响应

//发送 HTTP POST 请求
void login_register::test_http_post()
{
    //创建一个 QNetworkAccessManager 对象,用于发送网络请求。
    QNetworkAccessManager* pHttpMgr = new QNetworkAccessManager();

    // 设置url
    QString url = "http://127.0.0.1:8080/login";

    // 设置头信息
    QNetworkRequest requestInfo;
    requestInfo.setUrl(QUrl(url));
    requestInfo.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));

    // setRawData
    //就没有去获取用户输入,而是直接给默认的账户密码值
    QJsonObject rawJson;
    rawJson.insert("username", "zhangsan");
    rawJson.insert("password", "123456");

    //设置为json格式数据
    QByteArray byte_array = QJsonDocument(rawJson).toJson();
  
    // 发送post请求
    QNetworkReply* reply = pHttpMgr->post(requestInfo, byte_array);

    if (reply)
    {
        // 添加事件循环机制,请求完成时调用 post_requestFinished 函数处理响应,返回后再运行后面的
        connect(pHttpMgr, &QNetworkAccessManager::finished, 
            this, &login_register::post_requestFinished);
    }
}
2.3、获取请求结果并弹出消息提示框

然后调用函数执行post请求完成后的响应,获取请求状态码看是成功了还是失败了,弹出对应消息提示框

//处理 POST 请求完成后的响应。
void login_register::post_requestFinished(QNetworkReply* reply) 
{
    // 通过reply对象的 attribute 方法获取 HTTP 状态码,并将其存储在 QVariant 类型的变量statusCode。
    QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
    //如果状态码有效,则输出状态码的整数值到调试输出。
    if (statusCode.isValid())
        qDebug() << "status code=" << statusCode.toInt();

    //通过reply对象的 attribute 方法获取 HTTP 状态码的原因,并将其存储在 QVariant 类型的变量 reason。
    QVariant reason = reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
    //如果原因有效,则输出原因的字符串值到调试输出。
    if (reason.isValid())
        qDebug() << "reason=" << reason.toString();

    //获取 QNetworkReply 对象的错误状态。
    QNetworkReply::NetworkError err = reply->error();

    //如果错误状态不是 NoError,表示请求失败,进入错误处理逻辑。
    if (err != QNetworkReply::NoError) 
    {
        // 请求失败
        //再次获取 HTTP 状态码,用于显示错误信息。
        QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);

        //弹出消息框,显示请求失败的信息,包括状态码和错误信息。
        QMessageBox::information(this, "warn",
            "http post failed, error code = " + statusCode.toString() + " error info: " + reply->errorString());

        return;
    }
    else 
    {
        // 请求成功,进入成功处理逻辑。
        // 接收请求结果
        //读取响应数据,并存储在 QByteArray 类型的变量 responseByte 中。
        QByteArray responseByte = reply->readAll();
        QString strRes = responseByte; //将响应数据转换为字符串类型。

        //弹出消息框,显示请求成功的信息,包括响应数据。
        QMessageBox::information(this, "http post success",
            "post response = " + strRes);
    }
}
2.4超时请求处理函数

超时请求处理函数的大部分逻辑都是一样的,主要是发送请求后,添加了一个超时处理

注释写的还算清楚,大家可以多看看

//测试超时的 HTTP POST 请求。
void login_register::test_timeout_http_post()
{
    QNetworkAccessManager* pHttpMgr = new QNetworkAccessManager();

    // 设置url
    QString url = "http://127.0.0.1:8080/login";

    // 设置头信息
    QNetworkRequest requestInfo;
    requestInfo.setUrl(QUrl(url));
    requestInfo.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));

    // setRawData
    QJsonObject rawJson;
    rawJson.insert("username", "zhangsan");
    rawJson.insert("password", "123456");

    QByteArray byte_array = QJsonDocument(rawJson).toJson();

    // 发送post请求
    QNetworkReply* reply = pHttpMgr->post(requestInfo, byte_array);

// 添加超时处理,1ms超时
    QEventLoop eventloop;
    connect(reply, SIGNAL(finished()), &eventloop, SLOT(quit()));

    // 比如设置1ms内完成请求,否则就认为是超时
    //设置 1 秒后退出事件循环,模拟超时。
    QTimer::singleShot(1000, &eventloop, &QEventLoop::quit);
    eventloop.exec();

    QByteArray array;
    if (reply->isFinished())
    {
        if (reply->error() == QNetworkReply::NoError)
        {
            //正常结束,读取响应数据
            QByteArray result = reply->readAll();
            QString strRes = result;

            QMessageBox::information(this, "http post success",
                "post response = " + strRes);
        }
        else
        {
            // 异常结束
            // 请求失败
            QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);

            QMessageBox::information(this, "warn",
                "http post failed, error code = " + statusCode.toString() + " error info: " + reply->errorString());

            return;
        }
    }
    else
    {
        // 请求超时
        disconnect(reply, &QNetworkReply::finished, &eventloop, &QEventLoop::quit);
        reply->abort();
        
        QMessageBox::information(this, "http post timeout", "http post timeout");
    }

    reply->deleteLater(); //释放资源

以上就是如何使用Qt的网络模块发送HTTP、POST请求,并添加了超时处理的逻辑,以确保及时处理网络请求的超时情况的简单介绍

都看到这里了,点个赞再走呗朋友~

加油吧,预祝大家变得更强!

相关推荐
谈谈叭1 小时前
Javascript中的深浅拷贝以及实现方法
开发语言·javascript·ecmascript
lx学习1 小时前
Python学习26天
开发语言·python·学习
mengzhi啊2 小时前
Qt主线程把数据发给子线程,主线程会阻塞吗
qt·qthread
大今野2 小时前
python习题练习
开发语言·python
爱编程的鱼2 小时前
javascript用来干嘛的?赋予网站灵魂的语言
开发语言·javascript·ecmascript
捕鲸叉3 小时前
C++设计模式和编程框架两种设计元素的比较与相互关系
开发语言·c++·设计模式
未知陨落4 小时前
数据结构——二叉搜索树
开发语言·数据结构·c++·二叉搜索树
大波V54 小时前
设计模式-参考的雷丰阳老师直播课
java·开发语言·设计模式
无敌最俊朗@4 小时前
unity3d————接口基础知识点
开发语言·c#
一丝晨光5 小时前
gcc 1.c和g++ 1.c编译阶段有什么区别?如何知道g++编译默认会定义_GNU_SOURCE?
c语言·开发语言·c++·gnu·clang·gcc·g++