QML动态创建对象实战:从QML到C++的完整指南
1. 动态创建QML对象到底在解决什么问题QML 里写界面绝大多数时候我们都是在.qml文件里静态声明组件然后靠Loader、Repeater或者StackView这类容器去切换和复用。这套玩法在页面结构固定、数量可控的场景下非常舒服声明式、可读性强、绑定关系一目了然。但一旦遇到“数量不确定、结构由数据驱动、甚至组件类型都要运行时才能确定”的需求静态声明就开始捉襟见肘了。动态创建 QML 对象说的就是在 C 侧或者 QML 的 JavaScript 侧通过代码在运行时把组件实例化出来再挂到某个父对象上。它解决的核心问题有三个第一数量动态——比如一个标签列表用户点一次加一个事先根本不知道会有多少个第二类型动态——比如一个工具箱面板具体放哪个组件取决于后端下发的配置第三生命周期动态——对象什么时候创建、什么时候销毁完全由业务逻辑控制而不是跟着页面走。我最早接触这块是在做一个可配置的仪表盘项目用户能自己拖拽添加各种卡片每张卡片的类型、参数、位置都来自一份配置。当时第一反应是用Repeater配合model但很快就发现不行Repeater的 delegate 是固定的没法根据数据切换成完全不同的组件而且删除中间某一项时索引管理特别别扭。后来改用动态创建整个逻辑一下子就顺了。所以这篇就把我踩过的坑和总结出来的套路完整讲一遍从 QML 侧的Qt.createComponent到 C 侧的QQmlComponent再到内存管理和性能优化尽量让不同基础的读者都能直接抄作业。需要提前说明的是动态创建不是银弹。它能带来灵活性代价是失去了静态声明的一部分编译期检查和绑定自动管理。用得好是利器用不好就是内存泄漏和悬空指针的温床。下面我会把“什么时候该用、怎么用、怎么不出事”这三件事讲透。2. 两条技术路线QML 侧动态创建与 C 侧动态创建2.1 QML 侧Qt.createComponent 与 createObject 的配合QML 的 JavaScript 环境里动态创建主要靠两个 APIQt.createComponent()和组件实例的createObject()。前者负责把一段 QML 源码或者一个.qml文件解析成一个Component对象后者负责把这个Component实例化成真正的对象。最基础的写法是这样import QtQuick 2.15 Item { id: root width: 400 height: 300 Component { id: dynamicRect Rectangle { width: 100 height: 50 color: steelblue } } function addRect() { var obj dynamicRect.createObject(root, { x: 50, y: 50 }) if (obj null) { console.log(对象创建失败) } } Component.onCompleted: addRect() }这里createObject的第一个参数是父对象第二个参数是属性初始化字典。父对象决定了新对象的视觉层级和生命周期归属——父对象销毁时子对象默认也会被销毁。属性字典则是在对象构造阶段就把属性设好比创建完再逐个赋值更高效也能避免一些绑定被意外覆盖的问题。但更常见的场景是组件类型本身也不确定需要从字符串或者文件路径动态加载。这时候就用Qt.createComponentfunction createFromSource(source, parent, props) { var component Qt.createComponent(source) if (component.status Component.Ready) { return component.createObject(parent, props) } else if (component.status Component.Error) { console.log(加载失败:, component.errorString()) return null } return null }这里有个关键点Qt.createComponent是异步的。如果传入的是网络 URL 或者还没加载完的文件component.status会是Component.Loading这时候直接调createObject会失败。稳妥的做法是监听statusChanged信号等状态变成Ready再创建。很多人第一次写动态创建就栽在这里控制台报一堆 null 错误其实就是没等加载完。2.2 C 侧QQmlComponent 的完整控制力当动态创建的逻辑需要和 C 后端深度交互或者创建频率很高、对性能敏感时把这件事放到 C 侧会更合适。核心类是QQmlComponent用法和 QML 侧思路一致但控制粒度更细。一个典型的 C 动态创建流程是这样的QQmlEngine engine; QQmlComponent component(engine, QUrl(QStringLiteral(qrc:/DynamicItem.qml))); if (component.isReady()) { QObject *obj component.create(); if (obj) { // 设置父对象交给 QML 场景管理生命周期 obj-setParentItem(parentItem); } } else if (component.isLoading()) { // 连接 statusChanged 信号等加载完成再创建 QObject::connect(component, QQmlComponent::statusChanged, []() { if (component.isReady()) { QObject *obj component.create(); // ... } }); } else { qWarning() 组件错误: component.errorString(); }C 侧的优势在于可以在创建前做权限校验、可以从数据库或配置文件读取组件路径、可以在创建后立即拿到QObject*指针做类型转换和信号连接。而且QQmlComponent支持从QByteArray直接构造这意味着你甚至可以把 QML 源码存在数据库里运行时拼出来再实例化做真正的“配置即界面”。不过 C 侧也有代价你需要手动管理QQmlEngine和QQmlContext的关系如果对象创建后没有正确设置父对象就得自己负责 delete否则就是内存泄漏。这一点后面会专门讲。2.3 两条路线的选型对照对比维度QML 侧动态创建C 侧动态创建上手难度低纯 JS 语法中需要理解 QML 引擎生命周期适用场景界面逻辑为主、创建频率低数据驱动、高频创建、需与后端深度交互性能一般JS 解析有开销较好可复用 Component 对象内存管理父对象自动管理需手动设置父对象或手动 delete调试便利性控制台日志直观需要 qDebug 和错误字符串动态源码支持支持字符串源码支持 QByteArray 源码我个人的经验是如果动态创建的对象不超过几十个且逻辑都在前端QML 侧足够用如果涉及成百上千个对象的批量创建或者组件来源是后端配置果断上 C。两者也可以混用比如 C 负责从配置生成QQmlComponent并缓存QML 负责调用创建接口。3. 核心细节拆解从组件加载到对象挂载的完整链路3.1 组件加载的三种来源与各自坑点动态创建的第一步永远是拿到一个可用的Component。来源无非三种QML 文件路径、QML 源码字符串、已经存在的 Component 对象。这三种的坑点各不相同。文件路径方式最常见Qt.createComponent(MyItem.qml)或 C 的QQmlComponent(engine, QUrl(qrc:/MyItem.qml))。坑在于路径解析规则相对路径是相对于当前 QML 文件所在目录而不是相对于工作目录。我见过有人在qrc资源里写相对路径结果打包后找不到文件就是因为没搞清楚这个基准点。稳妥做法是一律用绝对路径或者qrc:/前缀。源码字符串方式适合做配置化界面比如从后端拿到一段 QML 片段直接实例化。写法是Qt.createQmlObject(qmlString, parent, filepath)注意第三个参数是用于错误报告的虚拟文件路径不传的话报错信息里会显示Unknown File排查起来很痛苦。这个 API 的坑在于字符串里的 import 语句必须完整不能依赖外部文件的 import而且每次调用都会重新解析性能不如复用 Component。已有 Component 对象方式性能最好因为解析只发生一次。你可以把常用的动态组件预先定义成Component需要时直接createObject。这也是我推荐的做法把动态组件集中在一个文件里声明用 id 引用既保留了静态声明的可读性又获得了动态创建的灵活性。3.2 createObject 的参数传递与属性初始化createObject(parent, properties)的第二个参数是个 JS 对象键值对会在对象构造时应用。这里有几个细节值得展开。第一属性名必须是该组件已声明的属性。如果你传了一个组件里不存在的属性QML 不会报错而是静默忽略。这个特性有时候是坑比如你拼错了属性名对象创建出来了但样式不对查半天才发现是拼写问题。建议在开发阶段打开QT_LOGGING_RULESqt.qml.binding.removal.infotrue之类的日志规则辅助排查。第二绑定表达式在属性字典里不会生效。比如你写{ width: parent.width / 2 }这里的parent.width会在字典求值时立即计算而不是建立绑定。如果希望动态建立绑定得用Qt.binding()包一层var obj component.createObject(root, { width: Qt.binding(function() { return root.width / 2 }) })第三信号处理器的连接。属性字典里不能直接写onClicked: ...因为那不是属性。正确做法是创建后单独连接var obj component.createObject(root) obj.clicked.connect(function() { console.log(被点击了) })3.3 父对象的选择与生命周期归属父对象决定了三件事视觉层级、坐标系统、生命周期。在 QML 里createObject的父参数如果是Item类型新对象会成为它的视觉子项如果是QObject类型非 Item则只有 QObject 父子关系没有视觉关系。生命周期这块要特别小心。QML 的规则是父对象销毁时子对象自动销毁。这听起来很省心但有个陷阱——如果你把动态对象的父对象设成了null那它就成了“孤儿”必须手动调用destroy()或者交给 JS 垃圾回收。而 JS 垃圾回收的时机是不确定的在对象还持有 C 资源或者信号连接时延迟销毁可能导致悬空引用。我的做法是永远给动态对象指定一个明确的父对象通常是某个容器 Item。如果确实需要“游离”状态那就用Qt.createQmlObject配合一个隐藏的容器作为父对象需要显示时再reparent。这样生命周期始终可控。4. 实操过程手把手实现一个可增删的动态卡片面板4.1 需求拆解与方案设计假设我们要做一个卡片面板用户可以点击按钮添加卡片每张卡片显示一个序号和随机颜色点击卡片上的删除按钮可以移除自己。卡片数量不固定样式统一但数据不同。方案设计用一个Column作为容器预先声明一个Component作为卡片模板添加时调用createObject并传入序号和颜色删除时调用对象自身的destroy()。这里选择 QML 侧动态创建因为逻辑简单、数量可控没必要上 C。4.2 卡片模板的编写要点Component { id: cardComponent Rectangle { id: card width: 300 height: 60 radius: 8 color: lightgray property int cardIndex: 0 Text { anchors.centerIn: parent text: 卡片 # card.cardIndex font.pixelSize: 16 } MouseArea { anchors.fill: parent onClicked: card.destroy() } } }模板里定义了一个cardIndex属性用于接收外部数据。注意destroy()是 QML 对象自带的方法调用后会从父对象中移除并释放。这里有个细节destroy()是延迟执行的不会立即从视觉树中消失如果紧接着要遍历子对象需要等一帧或者用destroyed信号。4.3 添加与删除的完整逻辑Column { id: container spacing: 10 anchors.centerIn: parent property int counter: 0 function addCard() { counter var color Qt.rgba(Math.random(), Math.random(), Math.random(), 1) var obj cardComponent.createObject(container, { cardIndex: counter, color: color }) if (obj null) { console.log(创建失败) counter-- } } } Button { text: 添加卡片 onClicked: container.addCard() }添加逻辑里做了失败回滚如果createObject返回 null把计数器减回去避免序号跳号。这个细节在实际项目里很重要否则用户会看到序号不连续以为是 bug。删除逻辑直接放在卡片的MouseArea里调destroy()简单直接。但如果删除后需要更新剩余卡片的序号就得遍历container.children重新赋值。这里要注意children包含的是视觉子项顺序和添加顺序一致但删除后索引会变遍历时最好用for倒序或者先收集再处理。4.4 参数计算颜色生成与序号管理颜色用Qt.rgba配合Math.random()生成取值范围 0 到 1。这里有个小技巧如果希望颜色不要太刺眼可以把随机值限制在 0.4 到 0.9 之间function randomChannel() { return 0.4 Math.random() * 0.5 }序号管理用容器上的counter属性只增不减。这样即使中间删除了卡片新添加的卡片序号也不会重复。如果业务要求序号连续那就得在删除后做重排重排逻辑建议放在删除操作之后延迟一帧执行等destroy()真正生效。5. 内存管理与性能优化动态创建最容易翻车的地方5.1 对象销毁的三种方式与适用场景动态创建的对象销毁方式有三种destroy()、父对象销毁连带、C 侧delete。三者的适用场景不同。destroy()是最常用的适合单个对象的精确移除。调用后对象会从父对象中摘除如果没有其他引用就会被垃圾回收。注意destroy()只能从 QML 侧调用C 侧没有这个方法。父对象销毁连带适合批量清理比如整个面板关闭时所有卡片自动销毁。这是最省心的方式前提是父子关系设置正确。C 侧delete适合 C 创建的对象或者需要在特定时机强制释放的场景。但要注意如果对象还被 QML 引擎引用比如有绑定指向它直接 delete 会导致悬空指针。稳妥做法是用deleteLater()让事件循环在安全时机释放。5.2 常见内存泄漏场景与排查方法场景一父对象为 null。createObject(null)创建的对象没有父对象如果忘记手动 destroy就会一直留在内存里。排查方法是定期打印engine-rootObjects()或者用 QML Profiler 看对象数量。场景二信号连接未断开。动态对象连接到外部对象的信号如果对象销毁时连接没断外部对象还持有引用可能导致对象无法回收。QML 的信号连接在对象销毁时通常会自动断开但 C 侧的connect需要手动disconnect或者用Qt::UniqueConnection。场景三JS 闭包持有引用。如果动态对象被某个 JS 数组或闭包引用即使调了destroy()垃圾回收也不会释放。排查方法是检查所有可能持有引用的地方用delete或者置 null 断开。我常用的排查手段是在创建和销毁时打日志统计当前存活对象数property int aliveCount: 0 function addCard() { var obj cardComponent.createObject(container, {...}) if (obj) { aliveCount obj.destroyed.connect(function() { aliveCount-- }) } }这样在控制台就能实时看到对象数量变化泄漏一眼就能发现。5.3 批量创建的性能优化技巧如果需要一次性创建大量对象比如 500 张卡片直接循环createObject会卡顿。优化思路有几个第一复用 Component 对象。Qt.createComponent每次调用都会重新解析应该只调一次把结果存起来复用。第二分批创建。用Timer或者Qt.callLater把创建操作分散到多帧避免阻塞 UI 线程。比如每帧创建 20 个500 个也就 25 帧用户几乎无感。第三考虑用Instantiator。这是 Qt 提供的一个专门用于动态批量创建的对象配合model使用性能比手动循环好而且自带延迟创建和销毁策略。如果需求是“根据模型批量生成”优先考虑Instantiator而不是手动createObject。第四避免在创建时做重计算。属性字典里的值尽量提前算好不要在字典里写复杂表达式因为每个对象构造时都会求值一次。6. 常见问题与排查技巧实录6.1 创建返回 null 的六种原因现象可能原因排查方法createObject 返回 null组件未加载完成检查 component.status 是否为 Ready控制台报错 Component is not ready异步加载未完成监听 statusChanged 信号对象创建了但看不见父对象不可见或尺寸为 0检查父对象 visible 和 width/height属性没生效属性名拼写错误或不存在对照组件声明逐个核对报错 Cannot assign to non-existent property属性字典里有未声明属性删除或改用动态属性创建后立即崩溃父对象类型不匹配Item 父对象只能挂 Item 子对象这张表是我从多次调试中总结出来的基本上覆盖了 90% 的 null 返回问题。其中“组件未加载完成”是最常见的尤其是从网络或者大文件加载时。6.2 动态对象绑定失效的排查思路动态创建的对象属性绑定有时候会莫名其妙失效。原因通常是属性字典里的绑定表达式在构造时被求值成了固定值。比如{ width: parent.width }这里的parent在字典求值时可能还是 null 或者旧值导致 width 被设成了错误的值而且不会随后续变化更新。解决办法是用Qt.binding()显式建立绑定或者创建后单独写绑定语句var obj component.createObject(parent) obj.width Qt.binding(function() { return parent.width / 2 })排查这类问题的技巧是在对象创建后打印属性值过一帧再打印一次如果两次值不同但绑定没更新那就是绑定失效了。6.3 删除对象时的时序陷阱destroy()是延迟执行的这意味着调用后对象不会立即消失。如果紧接着遍历children或者访问该对象可能会拿到已经标记删除但还没释放的对象导致不可预期的行为。我踩过的一个坑是删除卡片后立即重排序号结果遍历时把已删除的卡片也算进去了序号全乱。后来改成用destroyed信号回调里做重排或者用Qt.callLater延迟一帧执行问题就解决了。另一个陷阱是在对象的信号处理器里调用自身的destroy()比如onClicked: card.destroy()。这是安全的因为信号处理完成后对象才会真正销毁。但如果在destroy()之后还访问对象的属性就会拿到 undefined。6.4 独家避坑清单动态创建的对象父对象一定要显式指定不要图省事传 null。组件加载是异步的永远先检查 status不要假设立即可用。属性字典里的绑定用Qt.binding()包一层否则会变成静态值。批量创建用Instantiator或分批不要在主线程里循环几百次。删除对象后不要立即访问用destroyed信号或延迟一帧处理后续逻辑。开发阶段打开 QML 调试日志能提前发现很多绑定和属性问题。C 侧创建的对象如果交给 QML 管理记得setParentItem或setParent。动态对象的信号连接在对象销毁前手动断开避免悬空引用。7. 进阶玩法把动态创建和配置驱动结合起来7.1 从 JSON 配置生成界面动态创建真正发挥威力的场景是界面结构完全由配置决定。比如后端下发一份 JSON{ cards: [ { type: TextCard, title: 公告, content: ... }, { type: ImageCard, url: ... }, { type: ChartCard, data: [...] } ] }前端解析这份 JSON根据type字段选择对应的 Component然后动态创建。这样新增卡片类型只需要加一个 QML 文件和一条映射不用改主界面代码。实现上维护一个类型到组件路径的映射表property var componentMap: ({ TextCard: qrc:/cards/TextCard.qml, ImageCard: qrc:/cards/ImageCard.qml, ChartCard: qrc:/cards/ChartCard.qml }) function createCard(config) { var path componentMap[config.type] if (!path) return null var component Qt.createComponent(path) if (component.status ! Component.Ready) return null return component.createObject(container, config) }这里有个优化点可以把创建过的 Component 缓存到字典里避免重复解析同一个文件。7.2 动态组件的缓存策略缓存 Component 对象能显著提升重复创建的性能。做法是用一个 JS 对象做缓存property var componentCache: ({}) function getComponent(path) { if (componentCache[path]) { return componentCache[path] } var component Qt.createComponent(path) if (component.status Component.Ready) { componentCache[path] component } return component }注意缓存的是Component而不是创建出来的对象。Component可以复用多次创建实例但实例之间是独立的。缓存不需要手动清理因为Component本身很轻量而且会随引擎销毁。7.3 动态创建与 Loader 的取舍很多人会问既然有Loader为什么还要动态创建两者确实有重叠但定位不同。Loader适合“一个位置切换不同内容”的场景同一时间只有一个对象存活动态创建适合“多个对象并存、数量动态”的场景。如果需求是列表式的多个对象Repeater或Instantiator又比手动创建更合适。我的选择逻辑是单个位置切换用Loader固定模型列表用Repeater动态数量且需要精细控制用Instantiator完全运行时决定且逻辑复杂才手动createObject。不要为了动态而动态能用声明式解决的就别写命令式代码。8. 我个人在实际操作中的几点体会动态创建 QML 对象这件事我前后在好几个项目里用过最大的感受是它是一把需要克制使用的刀。刚学会的时候容易上头什么都想动态创建结果代码里全是createObject和destroy调试起来非常痛苦绑定关系藏在运行时静态分析工具也帮不上忙。后来我给自己定了几条规矩能用Repeater和Instantiator解决的绝不手动创建必须手动创建时把创建逻辑集中封装成一个函数不要散落在各处每个动态对象都要有明确的父对象和销毁路径开发阶段一定要打开 QML 日志把绑定失效和属性错误尽早暴露出来。还有一个小技巧分享在动态对象的模板里加一个Component.onCompleted日志打印自己的类型和关键属性这样在对象数量多的时候控制台能清晰看到创建顺序和参数排查问题效率高很多。配合Component.onDestruction日志创建和销毁成对出现内存泄漏一眼就能定位。最后说一个我踩过的最深的坑有一次在 C 侧创建对象后忘记设置父对象也没手动 delete结果每次刷新页面都泄漏一批对象跑了一晚上内存直接爆了。从那以后我在 C 侧创建对象的代码里第一行永远是设置父对象这个习惯救了我很多次。动态创建的自由度越高越需要纪律来兜底。

相关新闻

PyTorch DataLoader与容器模块:构建高效训练流程的必备指南

PyTorch DataLoader与容器模块:构建高效训练流程的必备指南

Zero基础学PyTorch,前面几篇已经过完了张量、自动求导、模型搭建这些基础。到了第五篇,咱们进入一个非常实际、也最容易让人卡住的话题:DataLoader。标题里写的是“Dataloder”,估计是少写了个a,它说的就是PyTorch的数…

2026/10/14 23:32:20 阅读更多 →
引擎基础系统与内存管理:地基级技术拆解

引擎基础系统与内存管理:地基级技术拆解

1. 为什么“基础系统”不是教科书里的概念,而是引擎开发者的生存线很多人第一次打开某跨平台引擎的源码仓库,看到Core/、Base/、Runtime/这些目录时,下意识觉得:“哦,这是底层,大概就是封装了点 STL 和 Win…

2026/10/14 23:32:20 阅读更多 →
LabVIEW箱线图设计源程序:从算法到多组数据对比实现

LabVIEW箱线图设计源程序:从算法到多组数据对比实现

很多人做数据分析和测试系统的时候,第一反应是用Python、用Matlab,但在LabVIEW里跑流程控制、采集控制和报表输出,这一套链路早就已经跑熟了。当你在LabVIEW里也想画个箱线图看看数据分布时——不好意思,原生控件没有。波形图、XY…

2026/10/14 23:32:20 阅读更多 →

最新新闻

2S串联电芯主动均衡方案:基于MP2642与STM32的BMS设计

2S串联电芯主动均衡方案:基于MP2642与STM32的BMS设计

/* 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 2:15:17 阅读更多 →
单片机C库运行时:libspace、多任务重入与中断安全实战

单片机C库运行时:libspace、多任务重入与中断安全实战

/* 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 2:15:17 阅读更多 →
Apache配置HTTP跳转HTTPS:两种稳定方案与常见坑解析

Apache配置HTTP跳转HTTPS:两种稳定方案与常见坑解析

/* 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 2:15:17 阅读更多 →
DES安全性复盘与3DES续命逻辑:从暴力破解到中间相遇攻击

DES安全性复盘与3DES续命逻辑:从暴力破解到中间相遇攻击

/* 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 2:15:17 阅读更多 →
隐式类型转换导致索引失效终结:从字符串与数字比较的底层逻辑切入

隐式类型转换导致索引失效终结:从字符串与数字比较的底层逻辑切入

在 MySQL 与各类关系型数据库调优中,有一个让无数开发和 DBA 既熟悉又抓狂的经典翻车案例:开发同学信誓旦旦地说:“大喜姐,我明明在 phone(手机号)字段上建了二级索引,为什么一跑生产查询&#…

2026/10/15 2:15:17 阅读更多 →
从零开始做SRC白帽:挖漏洞拿赏金,这些法律红线千万不要踩

从零开始做SRC白帽:挖漏洞拿赏金,这些法律红线千万不要踩

从零开始做SRC白帽:挖漏洞拿赏金,这些法律红线千万不要踩 很多新手入坑网络安全,初衷都很简单:想学一门硬核技术、靠挖漏洞赚赏金、做合法合规的白帽黑客。 我从纯零基础入门白帽,从零了解SRC规则、练习漏洞挖掘、提交…

2026/10/15 2:14:17 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

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

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

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

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

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

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

2026/10/14 16:30:29 阅读更多 →
影刀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/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/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练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/14 7:53:34 阅读更多 →