• Qt 之 全局的QNetworkAccessManager


    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


    前言

    在项目实践中,由于设备要与各种各样的资源通信,所以代码中各个模块都使用了自己的QNetworkAccessManager。
    在Qt的官方文档中,有如下说明:

    The QNetworkAccessManager class allows the application to send network requests and receive replies
    The Network Access API is constructed around one QNetworkAccessManager object, which holds the common configuration and settings for the requests it sends. It contains the proxy and cache configuration, as well as the signals related to such issues, and reply signals that can be used to monitor the progress of a network operation. One QNetworkAccessManager should be enough for the whole Qt application.


    翻译下来就是说:

    QNetworkAccessManager类允许应用程序发送网络请求和接收回复
    网络访问API是围绕一个QNetworkAccessManager对象构建的,该对象保存它发送的请求的公共配置和设置。它包含代理和缓存配置,以及与此类问题相关的信号,以及可用于监控网络操作进度的回复信号。一个QNetworkAccessManager应该足以支持整个Qt应用程序。

    就是说qt框架下,建议我们一个app用一个QNetworkAccessManager即可,这样删除和管理也都方便一些。
    QNetworkAccessManager不是线程安全的,全局网络访问应该在主线程中(或者通过信号post到主线程);

    代码实现

    我们设计了一个单例类来实现全局 QNetworkAccessManager的管理
    .h文件如下:

    #ifndef GLOBALNETWORKMANAGER_H
    #define GLOBALNETWORKMANAGER_H
    #include 
    
    class GlobalNetworkManager : public QObject
    {
    public:
        explicit GlobalNetworkManager(QObject *parent = nullptr);
    
        static void resetNetworkManager();
        static QNetworkAccessManager *getGlobalNetworkManager();
        static QPointer<QNetworkAccessManager> globalManager;   
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    .cpp文件:

    #include "globalnetworkmanager.h"
    #include 
    #include 
    #include 
    
    QPointer<QNetworkAccessManager> GlobalNetworkManager::globalManager = new QNetworkAccessManager;
    
    GlobalNetworkManager::GlobalNetworkManager(QObject *parent) : QObject(parent)
    {
    }
    
    void GlobalNetworkManager::resetNetworkManager()
    {
        if(globalManager)
        {
            delete globalManager;
            globalManager = NULL;
        }
        globalManager = new QNetworkAccessManager;
        if(globalManager == NULL)
        {
            qCritical() << "resetNetworkManager error";
        }
    }
    
    QNetworkAccessManager *GlobalNetworkManager::getGlobalNetworkManager()
    {
        Q_ASSERT(!qApp || QThread::currentThread() == qApp->thread());
        return globalManager;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    用法

    1.实现说明

    • 通过QPointer保存manager指针,防止悬垂指针;
    • 全局方法getGlobalNetworkManager内的断言保证了调用的正确性:
      QNetworkAccessManager不是线程安全的,全局网络访问应该在主线程中(或者通过信号post到主线程),保证全局的QNetworkAccessManager是在主线程中使用的。
    • 如果确实需要在子线程中进行网络访问,应该在子线程中重新创建一个manager.

    2.用法

    代码如下(示例):

    QNetworkAccessManager *pManager = GlobalNetworkManager::getGlobalNetworkManager();
    
    • 1

    别的模块中声明的QNetworkAccessManager *指针直接指向全局的QNetworkAccessManager即可。


    3. 如何删除QNetworkAccessManager 下的所有请求?

    if(globalManager)
    {
    QList list = globalManager->findChildren();
    qDebug() << func << “child size=” << list.size();
    foreach (QNetworkReply *t, list) {
    qDebug() << func << “before abort”;
    t->abort();
    }
    }

  • 相关阅读:
    视频监控系统/安防监控/视频AI智能分析:小动物识别算法场景汇总
    kubernetes之kubectl与YAML详解1
    修改bat文件默认编辑软件
    评测回顾 | 天空卫士以人为本的数据防泄露系统
    诈骗分子投递“大闸蟹礼品卡”,快递公司如何使用技术手段提前安全预警?
    对数据进行切片操作slice()函数
    《最新出炉》系列入门篇-Python+Playwright自动化测试-49-Route类拦截修改请求-下篇
    数字增益和模拟增益理解和示例
    LeetCode第22题-括号生成-java实现-图解思路与手撕代码
    Sparse稀疏检索介绍与实践
  • 原文地址:https://blog.csdn.net/u011942101/article/details/126918195