Qt/C++网络请求封装:QNetworkAccessManager统一管理与避坑指南
简介一套基于Qt框架的网络请求模块封装方案面向需要将HTTP通信与业务逻辑解耦的C/Qt开发者可快速解决网络层重复开发、调试不便、缺少请求日志等常见问题。资源共22个文件以cpp/h源码为主另含ui界面、Visual Studio工程配置和可执行示例压缩包整体约925KB结构紧凑便于按模块复用。方案基于QNetworkAccessManager、QNetworkRequest和QNetworkReply完成底层封装具体拆分为日志保存、网络请求助手、字符流交互、图片下载、上层界面演示五个部分既保留网络请求的通用性又通过日志记录提升排错效率。目前已有1193人学习适合具备一定Qt基础、希望在企业项目中规范网络层设计的中级开发者参考。1. 网络请求这层壳到底该包多厚在 Qt/C 做客户端最容易被拖进泥潭的不是界面而是网络请求的“重复造轮子”。每个页面都要 new 一个 QNetworkAccessManager、拼 QNetworkRequest、连 finished 信号、判断 error、再转 JSON——翻来覆去几十行换一个接口又得复制一份。这套 QNetWork 封装做的事情很直接把 QNetworkAccessManager 的细节吞进一个单例业务侧只暴露“传 URL、传参数、等回调”三个动作。GET/POST/PUT/DELETE、超时、失败重试、HTTP 状态码分类、线程安全全在模块里处理。适合两类人一类是 Qt 界面写了不少、但每次接后端接口都要从零贴网络模板的 C 开发者另一类是多人协作的桌面端项目想给团队定一个统一的请求出入口。2. 模块是怎么组织的目录划分、接口设计与一次请求的完整旅程2.1 目录结构与每个文件的职责这套封装没有把代码塞进一个巨型类里而是按“请求描述、结果描述、管理器”三层拆开。一个典型的目录布局长这样network/ ├── networkmanager.h / .cpp # 单例入口持有 QNetworkAccessManager管理 reply 生命周期 ├── networkrequest.h / .cpp # 请求参数结构体、HTTP 方法枚举 ├── networkresponse.h / .cpp # 统一响应对象httpCode、JSON 数据、错误信息、耗时 ├── networkcallback.h # 回调别名定义全部基于 std::function └── README.md # 使用示例与模块约定从文件名也能看出分工NetworkRequest 描述“我要请求什么”NetworkResponse 描述“我拿回了什么”NetworkManager 负责中间所有脏活。这样做的好处是业务层代码里不会出现 QNetworkReply、QNetworkRequest 这些 Qt 网络类型替换底层实现比如以后换成某跨平台系统的内部网络库时只动 NetworkManager 一个文件。我在实际项目里见过把 QNetworkAccessManager 直接塞进界面类的写法一旦请求变多析构顺序、信号断开、reply 释放全挤在一起查起来非常痛苦。2.2 一次 GET 请求从进入到返回的完整链路把封装后的调用展开其实底层还是标准的 QNetworkAccessManager 流程。以get(url, callback)为例整条链路是固定的业务层调用NetworkManager::instance()-get(QUrl(...), callback)传入接口地址和回调函数。NetworkManager 内部构造 QNetworkRequest设置 ContentType、User-Agent、重定向策略等默认头。调用m_mgr-get(request)拿到 QNetworkReply 指针这一步是异步的立即返回。将 reply 指针和当前请求的 callback、超时配置、重试计数一起登记到三个 QMap 中。连接 reply 的 finished 信号内部统一由onFinished(QNetworkReply*)处理。独立的 QTimer 每 500ms 扫描一次所有还在途的 reply超过超时时间的直接 abort。onFinished 里先做 HTTP 状态码判断、网络错误判断、重试判断最后取出 callback 并执行紧接着reply-deleteLater()释放。这七步里最关键的是第 4 步的映射关系。因为 QNetworkAccessManager 的 finished 信号只带一个 reply 参数你没法直接知道这个 reply 属于哪个业务请求所以封装的核心就是“用 reply 指针做 key把上下文信息挂在旁边”。回调风格的接口在阅读顺序上也是线性的发起请求和拿到结果写在同一处不用像信号槽那样把 connect 写在一个地方、槽函数定义在另一个地方。2.3 为什么用回调而不是业务信号这里插一个设计取舍。封装网络层时最常见的分歧是对外暴露信号槽还是暴露 std::function 回调对比维度信号槽方案std::function 回调方案生命周期接收者析构后信号连接可能悬空回调随 reply 一起在 onFinished 中取出天然配对并发区分需要额外传 requestId 来区分reply 指针天然隔离每个请求阅读顺序connect 在 A 处、处理逻辑在 B 处请求参数和后续处理写在同一段跨线程迁移依赖 Qt 信号队列行为偏隐式需要自己加锁但规则透明我个人倾向于在底层封装里用回调但暴露一层薄薄的信号包装给界面层。很多界面模块本来就是 QObject接到回调后emit someSignal(json)就能无缝转发两种风格都能兼顾。这份资源里也是这个思路封装主体基于回调但 NetworkManager 本身继承 QObject方便需要时发信号。3. 核心代码拆解QNetworkAccessManager 封装的关键实现3.1 统一的请求参数与响应结构网络封装的第一步是定义“请求长什么样”“结果长什么样”。下面这份 RequestOptions 结构体建议直接照抄到自己的工程里// networkrequest.h #pragma once #include QMap #include QByteArray enum class HttpMethod { GET, POST, PUT, DELETE }; struct RequestOptions { int timeoutMs 10000; // 超时时间默认 10 秒 int maxRetry 0; // 失败重试次数默认不重试 bool followRedirect true; // 是否跟随重定向 QMapQByteArray, QByteArray extraHeaders; // 额外请求头 void setHeader(const QByteArray key, const QByteArray value) { extraHeaders.insert(key, value); } };对应的响应对象不能只存一个 QString因为调用方往往需要同时判断 HTTP 状态、业务错误和原始 JSON// networkresponse.h #pragma once #include QJsonValue #include QString struct ApiResponse { int httpCode 0; // HTTP 状态码0 表示网络层错误 QJsonValue data; // 解析后的 JSON 数据 QString errorText; // 错误描述 qint64 costMs 0; // 请求耗时便于排查慢接口 bool ok() const { return httpCode 200 httpCode 300; } };这里有两个容易被忽略的参数说明。timeoutMs 的单位是毫秒很多人误以为 Qt 里设置超时也是“秒”实际 QNetworkRequest 的 transferTimeout 属性、以及我们这里的自定义超时逻辑都以毫秒为准。maxRetry 的默认值我刻意设成 0因为重试不是免费的——GET 请求重试还好POST 请求重试前必须确认接口是否幂等否则会造成重复下单或重复写数据。所以默认不重试调用方明确知道自己在做什么时再打开。3.2 Reply 与回调的映射几十个并发请求返回时怎么认领QNetworkAccessManager 本身支持任意多个并发请求难点在于 finished 信号里只有一个 QNetworkReply*。这就要靠映射表来认领。下面这段是 NetworkManager 的私有成员和 get 方法实现// networkmanager.h片段 class NetworkManager : public QObject { Q_OBJECT public: using Callback std::functionvoid(const ApiResponse); static NetworkManager* instance(); void get(const QUrl url, Callback cb, const RequestOptions opts RequestOptions()); private: explicit NetworkManager(QObject* parent nullptr); QNetworkAccessManager* m_mgr nullptr; QMutex m_mutex; QMapQNetworkReply*, Callback m_callbacks; // reply - 回调 QMapQNetworkReply*, RequestOptions m_opts; // reply - 请求配置 QMapQNetworkReply*, qint64 m_startTimes; // reply - 发起时间 QMapQNetworkReply*, int m_retryCounts; // reply - 已重试次数 QTimer m_timeoutTimer; };// networkmanager.cpp片段 void NetworkManager::get(const QUrl url, Callback cb, const RequestOptions opts) { QNetworkRequest req(url); req.setHeader(QNetworkRequest::ContentTypeHeader, application/json); req.setRawHeader(User-Agent, QNetWorkClient/1.0); if (opts.followRedirect) { req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy); } for (auto it opts.extraHeaders.begin(); it ! opts.extraHeaders.end(); it) { req.setRawHeader(it.key(), it.value()); } QNetworkReply* reply m_mgr-get(req); QMutexLocker locker(m_mutex); m_callbacks.insert(reply, std::move(cb)); m_opts.insert(reply, opts); m_startTimes.insert(reply, QDateTime::currentMSecsSinceEpoch()); m_retryCounts.insert(reply, 0); connect(reply, QNetworkReply::finished, this, [this, reply]() { handleReplyFinished(reply); }); }这段代码里的逻辑说明所有映射集合的 key 都是 QNetworkReply 指针这在 Qt 里是安全的因为同一时刻每个请求对应唯一一个 reply 对象指针不会重复。QMutexLocker 保护这些 QMap因为 QNetworkAccessManager 在特定配置下可能在其他线程派发 finished 信号多线程同时读写 QMap 会直接崩溃。startTimes 配合后面的定时器使用用来实现超时控制。3.3 超时调度与失败重试的实现QNetworkRequest 本身有 transferTimeout 属性可以设置超时但它的行为在某些平台下依赖底层协议栈表现不稳定。所以这套封装里我采用更可控的方式一个 500ms 的定时器定期扫描所有在途请求。这是超时检查的核心逻辑void NetworkManager::startTimeoutChecker() { m_timeoutTimer.setInterval(500); connect(m_timeoutTimer, QTimer::timeout, this, [this]() { qint64 now QDateTime::currentMSecsSinceEpoch(); QMutexLocker locker(m_mutex); for (auto it m_startTimes.begin(); it ! m_startTimes.end(); ) { QNetworkReply* reply it.key(); int timeoutMs m_opts.value(reply).timeoutMs; if (now - it.value() timeoutMs) { reply-abort(); // 注意abort 会触发 finished 信号 it m_startTimes.erase(it); } else { it; } } }); m_timeoutTimer.start(); }reply-abort()之后Qt 会照常发出 finished 信号所以 handleReplyFinished 里能看到一个 error 为 OperationCanceledError 的回复。接下来是重试逻辑的判断这也是最容易写错的地方void NetworkManager::handleReplyFinished(QNetworkReply* reply) { QMutexLocker locker(m_mutex); auto cb m_callbacks.take(reply); auto opts m_opts.take(reply); int retryCount m_retryCounts.take(reply); reply-deleteLater(); if (!cb) { return; // reply 已被 timeout 逻辑处理过或重复进入 } QNetworkReply::NetworkError netErr reply-error(); int httpCode reply-attribute( QNetworkRequest::HttpStatusCodeAttribute).toInt(); ApiResponse resp; resp.httpCode httpCode; bool wantRetry (netErr ! QNetworkReply::NoError) (retryCount opts.maxRetry); if (wantRetry) { const QUrl url reply-url(); retryCount; // 重新发起相同请求重试次数 1 QMetaObject::invokeMethod(this, [this, url, cb, opts, retryCount]() { QNetworkRequest req(url); // 这里必须重新设置所有请求头无法从旧 reply 中取回完整 request doSend(req, std::move(cb), opts, retryCount); }, Qt::QueuedConnection); return; } if (netErr ! QNetworkReply::NoError) { resp.errorText reply-errorString(); } else { const QByteArray raw reply-readAll(); resp.data QJsonDocument::fromJson(raw).object(); } resp.costMs QDateTime::currentMSecsSinceEpoch() - m_startTimes.value(reply, QDateTime::currentMSecsSinceEpoch()); // 注意锁在 cb 执行前释放避免业务回调里再请求网络造成死锁 locker.unlock(); cb(resp); }这段代码有一个特别值得注意的细节重试时通过 QMetaObject::invokeMethod 配合 QueuedConnection 把新请求投递到事件循环而不是在 finished 信号处理函数里直接调用m_mgr-get()。原因是当前正处于 reply 的 finished 信号派发栈中直接发新请求虽然通常也能工作但某些平台上会改变 QNetworkAccessManager 的内部状态导致异常。3.4 线程安全与跨线程回调前面代码里的 QMutex 保护了 QMap但还有一个隐藏问题回调执行时不能持有锁。如果业务回调里同步调用了另一个 NetworkManager 的方法比如一个请求完成后立刻发起下一个请求而锁还没有释放就会死锁。所以 handleReplyFinished 里在执行cb(resp)之前显式locker.unlock()。这是一个容易翻车的细节很多封装用 QMutexLocker 包住整个函数结果业务侧一旦在回调里嵌套请求程序直接卡死。我在第一次写完这个模块时也踩了这个坑检查了半小时才反应过来是锁的持有范围问题。跨线程的另一个注意点是NetworkManager 本身是 QObject如果调用 moveToThread 把它迁到工作线程那么构造函数里的 m_mgr 创建、定时器启动都要在工作线程完成不能简单 new 完再 move。常见做法是提供一个startInThread()方法在工作线程的初始化函数里统一创建 QNetworkAccessManager 和 QTimer。4. Qt 网络封装避坑指南4 个真实翻车位置4.1 SSL 证书开发机一跑就报 sslErrors外网环境又复现不出来现象接口地址是 https程序在开发机上运行第一次请求就触发 sslErrors 信号整个请求失败但同一套代码部署到某个测试服务器上又一切正常。原因开发机访问的是内网测试环境后端用了自签名证书或私有 CA而 Qt 默认只信任系统根证书库。解决开发阶段给 QNetworkAccessManager 的 sslErrors 信号加一个调试专用的处理器打印证书错误列表确认是证书链问题后把内网 CA 证书导入系统根证书库而不是直接ignoreSslErrors()一把梭。生产环境裸调 ignoreSslErrors 等于把数据安全全卖了只能当作临时调试手段。4.2 Windows 部署https 请求莫名失败缺了 OpenSSL 动态库现象程序在自己电脑上编译运行一切正常用 windeployqt 打包发给别的主机后所有 https 请求都失败http 却正常。原因Qt 的 QNetworkAccessManager 在 Windows 上做 TLS 握手依赖 OpenSSL 的 DLLlibcrypto 和 libsslwindeployqt 默认不一定会把这几个 DLL 拷进发布目录。解决打包后在 exe 同目录确认存在匹配 Qt 版本号的 OpenSSL DLL比如libssl-3-x64.dll和libcrypto-3-x64.dll如果用的静态编译版 Qt要确认 configure 时是否启用了 openssl 组件。排查手法是写一个最小 https GET 请求失败后看 QNetworkReply::errorString()如果提示 SSL handshake failed十有八九就是缺 DLL。4.3 finished 信号里回头再查 request取不回 POST 的 body现象封装里做了失败重试重试时想从reply-request()里把原始 POST 数据拿出来重新发送发现 request 里只有 URLbody 为空。原因QNetworkRequest 本身不保存你传给post(request, body)的 body 数据body 是直接交给 QNetworkAccessManager 底层发送的。解决在业务侧保留原始请求参数重试时用新的请求头和新 body 重新调用。一个实用做法是定义一个 InternalRequest 结构体把 url、method、body、回调、重试计数全部打包映射表 key 用递增的 requestId而不是直接用 reply 指针。4.4 200 不等于成功HTTP 状态码和业务码是两个维度现象接口正常返回httpCode 是 200但回调里拿到 data里面code字段是 50001代表“token 过期”。如果封装只判断 httpCode业务层就会把错误结果当成成功数据继续处理。原因很多后端设计里 HTTP 状态码只代表网关转发成功业务状态放在 JSON body 内部。解决在 ApiResponse 里预留一个 businessCode 字段或者把原始 JSON 完整交给调用方同时在文档里约定httpCode 负责网络层状态businessCode 负责业务层状态。我在封装里保留了data和errorText两个字段遇到这种混用协议的后端业务侧在回调函数里检查 data.code 就行。5. 跑起来最小可编译 Demo 与三个能直接上手的扩展点5.1 最小可编译 Demo把 NetworkManager 加到工程后用一个最小 main.cpp 验证整条链路#include QCoreApplication #include QDebug #include networkmanager.h int main(int argc, char* argv[]) { QCoreApplication app(argc, argv); NetworkManager* net NetworkManager::instance(); RequestOptions opts; opts.timeoutMs 5000; opts.maxRetry 1; net-get(QUrl(https://api.example.com/ping), [](const ApiResponse resp) { if (resp.ok()) { qDebug() online, httpCode: resp.httpCode , data: resp.data.toString(); } else { qDebug() failed, err: resp.errorText , httpCode: resp.httpCode; } QCoreApplication::quit(); }, opts); return app.exec(); }代码逻辑说明opts 里把超时调成 5 秒并允许重试 1 次回调里用 resp.ok() 判断整体结果。编译时把 network 目录下四个源码文件加进工程如果用的是 qmake在 .pro 文件里补一行QT network就行。5.2 扩展点 1给封装补一个带进度反馈的文件上传方法在二次开发的场景里上传文件是最常遇到的增量需求。可以在 NetworkManager 里加一个 upload 方法把 multipart/form-data 的拼装细节藏在内部void NetworkManager::upload(const QUrl url, const QString filePath, const QVariantMap formFields, Callback cb) { auto* multiPart new QHttpMultiPart(QHttpMultiPart::FormDataType); for (auto it formFields.begin(); it ! formFields.end(); it) { QHttpPart textPart; textPart.setHeader(QNetworkRequest::ContentDispositionHeader, QString(form-data; name\%1\).arg(it.key())); textPart.setBody(it.value().toString().toUtf8()); multiPart-appendPart(textPart); } QFile* file new QFile(filePath); file-open(QIODevice::ReadOnly); QHttpPart filePart; filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QString(form-data; name\file\; filename\%1\) .arg(QFileInfo(filePath).fileName())); filePart.setBodyDevice(file); file-setParent(multiPart); multiPart-appendPart(filePart); QNetworkRequest req(url); QNetworkReply* reply m_mgr-post(req, multiPart); multiPart-setParent(reply); // 确保 reply 销毁时 multipart 和 file 一起释放 QMutexLocker locker(m_mutex); m_callbacks.insert(reply, std::move(cb)); m_opts.insert(reply, RequestOptions()); m_startTimes.insert(reply, QDateTime::currentMSecsSinceEpoch()); m_retryCounts.insert(reply, 0); connect(reply, QNetworkReply::finished, this, [this, reply]() { handleReplyFinished(reply); }); }这里有一个容易踩的坑file 的父对象设为 multiPartmultiPart 的父对象设为 reply这样三者形成一条析构链否则文件句柄会在请求结束后泄漏。要监听上传进度的话再连一个 uploadProgress 信号即可。5.3 验证你改动的效果并发请求压测改完封装后用一个循环发几十个并发请求观察超时、重试、回调顺序是否正常QTimer* trigger new QTimer(app); int sentCount 0; QObject::connect(trigger, QTimer::timeout, []() { net-get(QUrl(https://api.example.com/search?qqt), [](const ApiResponse resp) { qDebug() resp resp.httpCode resp.costMs ms; }); if (sentCount 50) { trigger-stop(); } }); trigger-start(50);这段代码每 50ms 发一个请求连续发 50 个日志里能看到每个请求的耗时和状态码分布。重点观察两点一是所有回调是否都能在预期时间内返回二是总耗时接近线性增长还是乱序处理。如果发现某几个请求一直不回调优先怀疑定时器清理逻辑是不是把还没超时的 reply 误删了。这种验证方式不需要额外工具跑一遍日志心里就有底了。封装网络层这件事最深的体会是把请求上下文跟 reply 绑定在一起的这套映射思想比具体代码更重要。从那以后我每次做网络模块都会先把超时、重试、线程锁这三个边界画在纸上再动手写 QMap。这个模块后来在两个桌面客户端项目里复用过最稳的反而是看起来最简单的部分。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

移动电源新国标|详解异常温度记录功能实现方案

移动电源新国标|详解异常温度记录功能实现方案

简介移动电源新国标今年4月1号发布,号称历史最强标准,对行业的公司来说试一次考验。过渡期12个月,2027年4月1号将会强制实施新国标标准。新国标中有一项异常温度记录的要求,今天我们来解读一下什么意思?电量计怎么做才…

2026/10/16 2:27:53 阅读更多 →
双串磷酸铁锂主动均衡方案:MP2642GR-Z与TM4C1294的协同设计

双串磷酸铁锂主动均衡方案:MP2642GR-Z与TM4C1294的协同设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 2:27:53 阅读更多 →
计算机网络复习串讲:从分层模型到TCP/IP、HTTP与DNS核心考点

计算机网络复习串讲:从分层模型到TCP/IP、HTTP与DNS核心考点

如果你正被《计算机网络》搞得焦头烂额,相信我,不是你记忆力有问题,而是大多数人复习顺序从一开始就跑偏了。面对一堆协议、模型、状态码,第一反应就是死记硬背——背完就忘,忘了再背,越背越乱。这篇东西&a…

2026/10/16 2:27:53 阅读更多 →

最新新闻

SQL LIMIT 分页查询完全指南:语法、陷阱与性能优化

SQL LIMIT 分页查询完全指南:语法、陷阱与性能优化

1. 先把语法记牢:LIMIT 的两种写法和常见数据库差异LIMIT 看起来就是“截断结果集”这么简单,但实际用起来,不同数据库、不同写法、不同参数语义之间还是有很大差别的。我在帮业务方排查一个后台报表接口时,看到同事写了这么一句&…

2026/10/16 4:10:15 阅读更多 →
矩阵快速幂模板详解:从单位矩阵到__int128防溢出实战

矩阵快速幂模板详解:从单位矩阵到__int128防溢出实战

1. 从“矩阵快速幂不会”到“力扣模板直接秒”先说一下我为什么要写这题。去年某次集训,队友随机抽了一道信奥题让我讲,抽到的就是 P3390 模板。当时我第一反应是“这题不是背模板就行了吗”,结果真让我手写的时候,居然卡在了单位…

2026/10/16 4:10:15 阅读更多 →
PostgreSQL pg_hba.conf 配置实战:认证方式、IP限制与安全策略详解

PostgreSQL pg_hba.conf 配置实战:认证方式、IP限制与安全策略详解

数据库搞到一半连不上,连上来了密码报错,密码对了又被地址拒掉,好不容易调完规则发现又不生效——如果你也对pg_hba.conf有过这样的经历,那这篇内容就是为你准备的。作为 PostgreSQL 访问控制的第一道闸门,pg_hba.conf…

2026/10/16 4:10:15 阅读更多 →
Spring整合Kafka实战指南:核心原理、配置要点与常见坑全解析

Spring整合Kafka实战指南:核心原理、配置要点与常见坑全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 4:10:15 阅读更多 →
轻量级Python OCR验证码识别模型:ResNet18+CTC端到端方案

轻量级Python OCR验证码识别模型:ResNet18+CTC端到端方案

简介:本资源是一套面向Python开发者与信息安全从业者的高精度验证码OCR识别解决方案,聚焦网站自动化登录、爬虫反反爬绕过等实际场景,适合具备基础图像处理与机器学习知识的中高级开发者学习与二次开发。压缩包共76个文件,含47个核…

2026/10/16 4:10:15 阅读更多 →
STM32F407单相PWM整流器实现单位功率因数与能量回馈

STM32F407单相PWM整流器实现单位功率因数与能量回馈

简介:本资源是针对2022年全国大学生电子设计竞赛A题「单相交流电子负载」的完整嵌入式实现方案,面向STM32初学者、电赛备赛学生及电力电子方向实践者,重点解决单相系统下高精度锁相与PWM整流控制这一核心难点。工程基于STM32F407VET6主控&…

2026/10/16 4:09:14 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →