Qt与SQLite集成开发:从入门到实战的完整指南
1. 项目概述为什么Qt开发者绕不开SQLite如果你正在用Qt做桌面端、移动端或者嵌入式开发并且需要处理一些本地数据比如用户配置、日志记录、缓存文件或者一个中小型应用的核心数据存储那么你大概率会和我一样最终选择SQLite。这不是一个随意的决定而是经过无数次项目实战后得出的结论。Qt内置了完善的SQL模块支持而SQLite作为一个零配置、无服务器、单文件的数据库引擎它与Qt的集成简直是天作之合。你不需要安装任何额外的数据库服务编译时带上一个插件或者直接使用Qt提供的驱动就能让程序拥有一个强大、可靠的本地数据管理能力。我见过很多新手开发者一提到数据库就想着去连接MySQL或者PostgreSQL为了一个简单的数据存储功能引入复杂的客户端库、配置连接字符串、处理网络异常最后还把部署搞得异常麻烦。对于绝大多数本地存储场景这都属于“杀鸡用牛刀”不仅增加了开发和维护成本也引入了不必要的失败点。SQLite的设计哲学就是“简单”它把整个数据库包括定义、表、索引和数据本身存放在一个标准的磁盘文件中任何有文件读写权限的程序都可以访问它。这种特性与Qt的跨平台能力完美契合无论是在Windows、macOS、Linux还是在Android、iOS上你的数据文件格式都是一致的迁移和备份就是复制一个文件那么简单。所以当你的Qt应用需要持久化存储一些结构化的数据并且希望这个方案足够轻量、足够可靠、足够简单时SQLite就是那个“标准答案”。接下来我不会只给你一堆干巴巴的代码片段而是会带你走一遍从环境准备、数据库操作到实战优化的完整流程并分享那些只有踩过坑才知道的细节。我们争取在五分钟内让你掌握核心用法但深入理解其中的门道可能需要你花更多时间反复实践。2. 环境准备与核心对象初识在开始写代码之前我们需要确保开发环境是就绪的。如果你使用的是Qt Creator并且通过Qt Installer安装了某个版本的Qt比如Qt 5.15或Qt 6.x那么SQL的支持默认就是包含在内的。你不需要单独下载SQLite因为Qt的SQLite驱动是基于SQLite的C接口封装而成的通常已经编译好并集成在Qt的插件目录里了。2.1 在项目文件中启用SQL模块第一步打开你的项目配置文件.pro文件。这是Qt项目构建的蓝图你需要在这里告诉qmakeQt的构建工具“我这个项目要用到SQL模块”。操作非常简单只需添加一行QT sql这行代码的作用是让构建系统在链接阶段将Qt SQL模块的库文件如Qt5Sql或Qt6Sql链接到你的可执行文件中。没有这一步你在代码里#include QSqlDatabase的时候编译可能会通过因为头文件存在但链接时会报错提示找不到相关的函数实现。加上之后Qt Creator的代码补全功能也会自动识别SQL相关的类提升编码效率。2.2 理解Qt SQL模块的核心类Qt SQL模块提供了一组类来统一地操作数据库无论后端是SQLite、MySQL还是PostgreSQL。在编写第一行数据库代码前花两分钟了解这几个核心类后续操作会顺畅很多QSqlDatabase 这是数据库连接的抽象。你可以把它理解为一个通往具体数据库的“门”或“会话”。通过它你可以建立连接、执行SQL语句、管理事务。一个应用程序可以同时创建多个QSqlDatabase实例连接到不同的数据库甚至不同类型的数据-库。QSqlQuery 这是执行SQL语句和遍历结果集的主要工具。无论是执行一条CREATE TABLE的DDL语句还是执行带参数的INSERT、SELECT亦或是遍历查询返回的多行数据都是通过QSqlQuery对象来完成。它是我们打交道最多的类。QSqlTableModel / QSqlQueryModel 这两个是高级别的抽象用于将数据库中的数据与Qt的模型/视图框架如QTableView无缝集成。QSqlTableModel可以直接映射到一张数据库表提供开箱即用的编辑和排序功能QSqlQueryModel则用于展示任意SELECT查询的结果通常是只读的。如果你需要快速做一个数据管理界面它们能省去大量手动处理数据的代码。对于入门我们重点关注前两个。QSqlDatabase负责“开门”QSqlQuery负责“进去干活”。有了这个基本概念我们就可以开始创建第一个数据库了。3. 从零开始创建并连接你的第一个SQLite数据库理论说再多不如动手一试。我们从一个最简单的场景开始在程序启动时检查当前目录下是否存在一个数据库文件如果不存在就创建它并建立连接。3.1 建立数据库连接在C代码中通常是在main.cpp或某个初始化函数里我们这样操作#include QCoreApplication // 如果是控制台程序用这个 // #include QApplication // 如果是GUI程序用这个 #include QSqlDatabase #include QSqlError #include QDebug int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 1. 添加SQLite数据库驱动并创建一个连接 QSqlDatabase db QSqlDatabase::addDatabase(QSQLITE); // 2. 设置数据库文件路径。这里使用相对路径会在程序运行目录下创建test.db文件 // 你也可以使用绝对路径如 “C:/Users/Name/data.db” db.setDatabaseName(test.db); // 3. 尝试打开数据库连接 if (!db.open()) { qCritical() 无法打开数据库: db.lastError().text(); return -1; } qDebug() 数据库连接成功; // ... 后续的数据库操作将在这里进行 return a.exec(); }我们来拆解一下这几行关键代码QSqlDatabase::addDatabase(“QSQLITE”) 静态函数用于添加一个指定类型的数据库连接。参数”QSQLITE”是Qt内置的SQLite驱动标识符。这个函数会返回一个QSqlDatabase对象并且将这个连接以默认连接未指定连接名的形式注册到全局。后续我们可以通过QSqlDatabase::database()来获取这个默认连接。setDatabaseName() 对于SQLite驱动这个函数参数不是传统意义上的数据库名而是数据库文件的磁盘路径。这是新手最容易混淆的一点。你传入”test.db”它就会在当前目录寻找或创建test.db文件传入”:memory:”则会创建一个纯内存数据库程序关闭后数据消失常用于临时计算或测试。db.open() 真正尝试建立连接。对于文件型SQLite如果文件不存在open()操作会自动创建一个空的数据库文件。所以创建数据库文件的操作是隐式的无需额外命令。如果文件已存在则直接打开。这个函数返回bool失败时可以通过db.lastError()获取详细的错误信息。注意 数据库文件路径的选择有讲究。在开发阶段放在程序当前目录很方便。但在发布应用时特别是跨平台或涉及用户权限的系统如Linux的/usr/bin或Windows的Program Files程序可能没有在当前目录的写入权限。更专业的做法是使用QStandardPaths类来获取适合存储应用数据的标准路径例如QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)。3.2 执行第一条SQL语句创建表连接建立后里面是空的没有表。我们需要执行SQL语句来创建表结构。这里就轮到QSqlQuery出场了。// 接上面的代码在 db.open() 成功之后 QSqlQuery query; // 创建一张用户表 QString createTableSQL R( CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL UNIQUE, email TEXT, age INTEGER, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ) ); if (!query.exec(createTableSQL)) { qCritical() 创建表失败: query.lastError().text(); } else { qDebug() 表‘users’创建成功或已存在。; }我们定义了一个QSqlQuery对象query。它默认使用我们之前建立的默认数据库连接。将创建表的SQL语句写在一个字符串里。这里使用了C11的原始字符串字面量R”(…)”让多行SQL的书写更加清晰避免了很多转义问题。使用query.exec(sql)来执行这条SQL语句。它同样返回一个bool表示成功与否。CREATE TABLE IF NOT EXISTS是一个好习惯。它确保表不存在时才创建避免了因重复执行创建语句而导致的错误使得这段初始化代码可以安全地多次运行。到这里一个最基本的、包含一张表的SQLite数据库就已经在你的Qt程序里跑起来了。你可能觉得这太简单但这就是SQLiteQt的核心优势——用最小的代价获得可用的数据持久化能力。接下来我们要往里面增删改查数据并处理一些更实际的问题。4. 核心操作详解安全高效地增删改查直接拼接SQL字符串执行操作对于学习来说是直观的但在实际项目中这却是安全性和稳定性的“头号杀手”。尤其是当操作涉及用户输入时比如INSERT INTO users (username) VALUES (‘” userInput “‘)如果userInput里包含一个单引号就会破坏SQL语法更可怕的是可能引发“SQL注入”攻击。因此我们必须使用参数化查询。4.1 参数化插入防止SQL注入的黄金法则假设我们要向users表插入一条新用户记录正确做法如下QSqlQuery query; query.prepare(INSERT INTO users (username, email, age) VALUES (?, ?, ?)); // 绑定参数值。注意索引从1开始而不是0。 query.addBindValue(张三); query.addBindValue(zhangsanexample.com); query.addBindValue(25); if (!query.exec()) { qCritical() 插入数据失败: query.lastError().text(); } else { qDebug() 插入成功新记录ID: query.lastInsertId().toInt(); }关键点解析prepare(): 这个方法用于“预处理”一条SQL语句。语句中的?是占位符。数据库驱动会先编译这条语句的模板后续只需传入不同的参数值即可执行效率更高且最关键的是安全。addBindValue(): 按照SQL语句中?出现的顺序依次将实际的值绑定上去。Qt会自动处理类型转换和字符串转义。即使用户名是O‘Brien这样的字符串单引号也会被正确转义确保它只是作为一个字符串值被插入而不会成为SQL语法的一部分。lastInsertId(): 对于具有自增主键AUTOINCREMENT的表插入成功后可以通过这个函数获取新生成的主键ID这在需要建立表关联时非常有用。你也可以使用命名占位符让代码更清晰query.prepare(“INSERT INTO users (username, email, age) VALUES (:name, :email, :age)”); query.bindValue(“:name”, “李四”); query.bindValue(“:email”, “lisiexample.com”); query.bindValue(“:age”, 30); query.exec();4.2 查询与遍历处理结果集的正确姿势插入数据后我们当然要把它查出来。QSqlQuery在执行SELECT语句后会维护一个指向结果集的“游标”。QSqlQuery query; if (!query.exec(“SELECT id, username, email, age FROM users”)) { qCritical() “查询失败:” query.lastError().text(); return; } qDebug() “查询结果:”; while (query.next()) { int id query.value(“id”).toInt(); QString name query.value(“username”).toString(); QString email query.value(“email”).toString(); int age query.value(“age”).toInt(); qDebug() QString(“ID: %1, 用户名: %2, 邮箱: %3, 年龄: %4”) .arg(id).arg(name).arg(email).arg(age); }query.exec()执行查询。query.next(): 这是遍历结果集的核心。它把游标移动到下一行记录。首次调用时游标位于第一行之前所以通常用while(query.next())来循环。当没有更多行时next()返回false。query.value(): 获取当前行中指定列的值。参数可以是列的索引从0开始也可以是列名的字符串。强烈建议使用列名这样即使你调整了SELECT语句中字段的顺序代码也不会出错。它返回一个QVariant这是Qt中用于包装各种类型的通用容器你需要用.toInt(),.toString()等方法将其转换为具体类型。4.3 更新与删除同样需要参数化更新和删除操作同样要使用参数化查询尤其是WHERE条件中的值。// 更新操作 QSqlQuery updateQuery; updateQuery.prepare(“UPDATE users SET age :newAge WHERE username :name”); updateQuery.bindValue(“:newAge”, 26); updateQuery.bindValue(“:name”, “张三”); if (!updateQuery.exec()) { qCritical() “更新失败:” updateQuery.lastError().text(); } else { qDebug() “更新了” updateQuery.numRowsAffected() “行数据”; } // 删除操作 QSqlQuery deleteQuery; deleteQuery.prepare(“DELETE FROM users WHERE age :minAge”); deleteQuery.bindValue(“:minAge”, 18); if (!deleteQuery.exec()) { qCritical() “删除失败:” deleteQuery.lastError().text(); }numRowsAffected(): 对于UPDATE和DELETE语句这个方法返回受影响的记录行数可以用于判断操作是否如预期执行。掌握了这些你已经能够完成一个本地Qt应用90%的数据库交互需求了。但是要把东西做得扎实我们还得聊聊那些容易踩坑的地方和进阶技巧。5. 避坑指南与性能优化实战在实际项目中直接使用原始的QSqlQuery进行所有操作随着业务复杂代码会变得难以维护。而且一些细节处理不好会导致程序崩溃或性能低下。5.1 连接管理不要滥用全局默认连接前面的例子一直使用addDatabase时不指定连接名这使用的是默认连接。在简单的单线程、单数据库应用中没问题。但如果你的应用需要连接多个数据库或者在多线程环境下操作数据库就必须管理好连接名。// 创建第一个连接命名为 “conn1” QSqlDatabase db1 QSqlDatabase::addDatabase(“QSQLITE”, “conn1”); db1.setDatabaseName(“database1.db”); db1.open(); // 创建第二个连接命名为 “conn2” QSqlDatabase db2 QSqlDatabase::addDatabase(“QSQLITE”, “conn2”); db2.setDatabaseName(“database2.db”); db2.open(); // 在使用时通过连接名获取特定的数据库连接 QSqlDatabase specificDB QSqlDatabase::database(“conn1”); QSqlQuery query(specificDB); // 将特定连接传递给QSqlQuery构造函数 query.exec(“SELECT * FROM table1”);重要原则 SQLite的同一个数据库连接不是线程安全的。你不能在多个线程中同时使用同一个QSqlDatabase对象或由它创建的QSqlQuery对象。Qt官方推荐的做法是每个线程创建自己独立的数据库连接。即使它们指向同一个数据库文件也要通过不同的连接名来建立。SQLite内部会处理文件锁但Qt层面的对象不能跨线程共享。5.2 事务处理保证数据一致性与大幅提升性能当你需要执行一系列更新操作比如转账一个账户扣钱另一个账户加钱时必须使用事务。事务可以确保这一系列操作要么全部成功要么全部失败回滚保证数据的完整性。此外对于大批量的INSERT操作将其包裹在事务中性能可以有数量级的提升因为SQLite默认每条语句都是一个独立的事务自动提交频繁的磁盘同步会极大拖慢速度。QSqlDatabase::database().transaction(); // 开始一个事务 QSqlQuery query; bool success true; // 假设要插入10000条数据 for (int i 0; i 10000; i) { query.prepare(“INSERT INTO logs (message) VALUES (?)”); query.addBindValue(QString(“Log entry %1”).arg(i)); if (!query.exec()) { success false; break; // 有一条失败就跳出 } } if (success) { QSqlDatabase::database().commit(); // 全部成功提交事务 qDebug() “批量插入成功已提交”; } else { QSqlDatabase::database().rollback(); // 有失败回滚事务所有插入无效 qCritical() “批量插入失败已回滚:” query.lastError().text(); }实测对比 在我的一个项目中向SQLite插入10万条简单记录不使用事务耗时超过2分钟而使用事务后仅需不到2秒。这个差异是决定性的。5.3 错误处理不要忽略lastError()这是新手和老手的一个显著区别。新手写完query.exec()就以为万事大吉。老手一定会检查返回值并在失败时查看lastError()。SQLite的错误信息通常很明确比如“table users already exists”表已存在、“no such column: address”列不存在等。将错误信息记录到日志或显示给用户开发阶段是快速定位问题的关键。在生产环境中你可能需要定义更优雅的错误恢复机制但最基本的检查绝不能少。5.4 使用QSqlTableModel快速构建GUI如果你正在开发一个带界面的管理程序需要展示和编辑数据库表手动用QSqlQuery取数据再填充到QTableWidget里就太原始了。Qt的模型/视图框架提供了QSqlTableModel可以极大简化这项工作。// 假设在某个窗口类的初始化函数中 QSqlTableModel *model new QSqlTableModel(this); model-setTable(“users”); // 指定关联的表 model-setEditStrategy(QSqlTableModel::OnManualSubmit); // 设置编辑策略手动提交 model-select(); // 从数据库加载数据 // 将模型设置给一个TableView ui-tableView-setModel(model); ui-tableView-setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed);短短几行代码你就得到了一个可以显示、排序、编辑双击单元格用户表的界面。编辑策略OnManualSubmit意味着用户在界面上的修改不会立即写入数据库直到你调用model-submitAll()。这给了你进行验证或批量提交的机会。当然你也可以设置为OnFieldChange字段变化即提交或OnRowChange行变化即提交。6. 部署与调试让程序带着数据库一起走开发调试时数据库文件放在项目根目录很方便。但发布软件时你需要考虑数据库文件的存放位置。6.1 确定数据库文件的可写路径你不能假设用户有权限在程序安装目录如C:\Program Files下创建或写入文件。正确的做法是使用QStandardPaths来获取一个适合存放应用数据的目录。QString dataDir QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); QDir dir(dataDir); if (!dir.exists()) { dir.mkpath(“.”); // 递归创建目录 } QString dbPath dir.filePath(“myapp_data.db”); QSqlDatabase db QSqlDatabase::addDatabase(“QSQLITE”); db.setDatabaseName(dbPath); // ... 后续操作QStandardPaths::AppDataLocation会根据操作系统返回一个标准路径例如Windows:C:\Users\Username\AppData\Roaming\AppNamemacOS:/Users/Username/Library/Application Support/AppNameLinux:/home/Username/.local/share/AppName这样既能保证用户有写入权限也符合各操作系统的规范。6.2 使用可视化工具调试数据库在开发过程中你肯定需要查看数据库里到底存了什么数据格式对不对。直接打开二进制的.db文件是看不懂的。你需要一个SQLite可视化工具。我强烈推荐DB Browser for SQLite (DB4S)。它是开源、免费、跨平台的界面直观可以浏览表结构、执行SQL语句、导入导出数据是调试SQLite的利器。你可以从它的官网或GitHub页面下载。当你的程序插入数据后用DB4S打开同一个数据库文件就能实时验证操作结果排查问题效率倍增。6.3 处理数据库迁移与升级这是应用迭代中必然会遇到的问题。第一个版本你创建了v1.0的表结构。到了v1.1版本你需要增加一个新字段或者修改某个字段的类型。你不能简单地在启动时执行CREATE TABLE IF NOT EXISTS因为对于老用户表已经存在这条语句会被跳过新字段不会被添加。一个常见的简单策略是在数据库中维护一个版本号可以是一张叫version的单独表或者一个用户自定义的PRAGMA值。程序启动时读取当前数据库版本与代码中期望的版本对比。如果版本低则按顺序执行一系列升级脚本ALTER TABLE ADD COLUMN …等最后更新版本号。int currentVersion getDatabaseVersion(); // 自定义函数从数据库读取当前版本 int expectedVersion 2; if (currentVersion expectedVersion) { QSqlDatabase::database().transaction(); if (currentVersion 1) { // 执行从v1到v2的升级脚本 QSqlQuery(“ALTER TABLE users ADD COLUMN phone TEXT”); setDatabaseVersion(2); // 更新版本号为2 } // 未来可以继续添加 else if (currentVersion 2) { … } QSqlDatabase::database().commit(); }这个方案虽然简单但对于中小型项目已经足够。更复杂的项目可能会使用专门的数据库迁移框架。走到这一步你已经超越了“五分钟入门”的范畴开始以一个更工程化的视角来使用Qt和SQLite了。记住技术工具的价值在于解决实际问题SQLite的轻便与Qt的优雅结合为你处理本地数据存储提供了一个近乎完美的解决方案。剩下的就是在具体的项目中去实践、去优化、去积累属于你自己的经验了。

相关新闻

C++零基础入门指南:从命令行编译到STL实战项目

C++零基础入门指南:从命令行编译到STL实战项目

1. 从“Hello World”到“我能写点什么”:零基础的心理建设与起点选择 看到这个标题,你可能会想,又是一篇老生常谈的“学习路线”。但我想说的是,这份路线图,是我和身边很多朋友,从对着黑框框敲下第一个“H…

2026/9/30 11:19:13 阅读更多 →
VSCodium:开源纯净的VS Code替代品,隐私与自由之选

VSCodium:开源纯净的VS Code替代品,隐私与自由之选

1. 项目概述:当我们在谈论VSCode时,我们在谈论什么? 如果你是一名开发者,那么Visual Studio Code(简称VS Code)这个名字对你来说,可能就像空气和水一样自然。它几乎成了现代编程的代名词&#…

2026/10/6 10:19:20 阅读更多 →
大模型增强工具实战:从环境配置到工作流集成

大模型增强工具实战:从环境配置到工作流集成

1. 先搞清楚“克隆对决”到底在比什么 看到“GPT Luna Max”和“Claude Fable”这两个名字,很多人第一反应可能是“哪个模型更强”。但如果你真的去搜,会发现一个关键问题: 这两个名字,很可能不是官方发布的模型,而是…

2026/10/11 23:40:17 阅读更多 →

最新新闻

从 1080P 到 4K:Video2X 的 Qt6 界面把视频超分辨率与帧插值做成四步

从 1080P 到 4K:Video2X 的 Qt6 界面把视频超分辨率与帧插值做成四步

从 1080P 到 4K:Video2X 的 Qt6 界面把视频超分辨率与帧插值做成四步 【免费下载链接】video2x A machine learning-based video super resolution and frame interpolation framework. Est. Hack the Valley II, 2018. 项目地址: https://gitcode.com/GitHub_Tre…

2026/10/14 5:16:02 阅读更多 →
用RAG盘活老师傅经验:制造业设备手册解析与故障诊断开源框架

用RAG盘活老师傅经验:制造业设备手册解析与故障诊断开源框架

制造业里攒文档的速度,永远赶不上老师傅退休的速度。我见过不少车间,设备手册摞起来半人高,故障代码表散落在三四个系统里,老师傅随口一句“这声音不对”,新来的维护工要翻半天手册才敢动手。我一直在琢磨怎么用RAG把这…

2026/10/14 5:16:02 阅读更多 →
工业AI落地制造现场:从缺陷检测到工艺优化的实战观察

工业AI落地制造现场:从缺陷检测到工艺优化的实战观察

这几年我跑了不少制造工厂,从汽车零部件、家电组装到电子产线,都待过一阵子。发现一个有趣的现象:“工业AI”这个词人人都在喊,真正把模型嵌进产线、天天跑数据的其实没多少。许多人把工业AI想象成科幻片里的机器人代替工人&#…

2026/10/14 5:16:02 阅读更多 →
C++与AI框架:从LibTorch部署到推理引擎的工程实战

C++与AI框架:从LibTorch部署到推理引擎的工程实战

1. 为什么AI圈子里C依然是硬通货在Python几乎统治了算法实验和模型训练脚本的今天,聊C与人工智能框架这个话题,听起来像是考古。但真正把AI系统推到生产环境的人,大概率都明白一个事实:Python是AI的壳,C才是AI的魂。先…

2026/10/14 5:16:02 阅读更多 →
codelin 统一 Claude Code 级别智能编程助手:UnifiedClaudeCodeAssistant 功能整合实现全解析

codelin 统一 Claude Code 级别智能编程助手:UnifiedClaudeCodeAssistant 功能整合实现全解析

人工智能大模型AI Agent代码智能体工具调用MCP 服务RAG交互助手 【免费下载链接】codelin 项目地址: https://gitcode.com/Cangjie-SIG/codelin 点击查看 免费下载 导读:本文以 codelin 智能编程助手的“统一功能整合”为主线,完整拆解其基于…

2026/10/14 5:16:02 阅读更多 →
Small Agent为何要从生成式推理转向分类式推理

Small Agent为何要从生成式推理转向分类式推理

1. 为什么“生成式推理”正在拖慢 Small Agent 的实际落地?你有没有遇到过这样的场景:一个轻量级的智能体(Small Agent),部署在边缘设备上,响应延迟要求低于200毫秒,但每次执行“判断用户意图”…

2026/10/14 5:15:02 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 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/13 22:01:27 阅读更多 →
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/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练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/12 18:11:17 阅读更多 →