MFC ChartCtrl 快速实现实时波形显示:从集成到性能优化

简介:这份源码资源面向具备一定C++基础的Windows开发者,尤其是需要在MFC工程中快速实现数据可视化的初学者与进阶者。它围绕ChartCtrl控件展开,演示了从控件初始化、波形数据组织、折线绘制到定时刷新与鼠标交互事件处理的完整流程,可帮助读者理解在VC++对话框程序中嵌入图表控件并驱动动态波形显示的核心思路。资源包共80个文件,以36个h头文件与26个cpp源文件为主体,辅以inl内联实现、ico图标、vcxproj工程文件、rc资源脚本及sln解决方案等,压缩包约41.86MB,工程结构完整,可直接用VS2015企业版打开编译运行。目前已有3852人学习下载,适合作为MFC图表开发的入门范例,通过阅读与调试源码,读者能掌握AddSeries、坐标轴设定、数据点追加及OnTimer刷新等关键用法,并借鉴颜色、网格线、图例等美化技巧,为后续开发实时监控或数据分析类界面打下基础。

1. 从一块“画不出波形”的工控屏说起:ChartCtrl 到底能省多少事

前阵子帮一个做数据采集的朋友看代码,他那个 MFC 上位机要实时显示 8 通道的电压波形,一开始用自绘 CDC 硬画,结果刷新一快就闪屏,鼠标拖动窗口直接卡成幻灯片。后来换成 ChartCtrl 控件,同样的硬件、同样的采样率,波形稳了,代码量还砍掉一大半。这件事让我意识到,很多做 MFC 上位机的同行其实卡在同一个地方:不是不会采数据,而是不知道怎么把数据“又快又稳”地画出来。

这份《MFC 利用 ChartCtrl 快速实现波形显示实例源码》要解决的正是这个痛点。ChartCtrl 是一个基于 MFC 的免费图表控件库,封装了坐标轴、曲线、图例、网格这些常用元素,你不需要从 GDI 的 MoveTo/LineTo 开始啃,只要把数据点喂进去,它负责渲染。适合谁?做工业上位机、仪器仪表界面、传感器数据监控的 C++ 开发者,尤其是那些用 MFC 做界面、又不想引入 Qt 或第三方商业图表库的团队。源码包里通常包含控件源码、示例工程和必要的头文件,拿到手编译就能跑起来看效果。

2. ChartCtrl 的绘图机制与工程集成:为什么它比自绘 CDC 稳

2.1 双缓冲与分层渲染:闪屏问题的根源在哪

自绘 CDC 闪屏的根本原因,是每次重绘都直接往屏幕 DC 上画,窗口一刷新,背景擦除和前景绘制之间有个时间差,人眼就看到了闪烁。ChartCtrl 内部做了两件事:一是用内存 DC 做双缓冲,所有绘制先在内存位图上完成,再一次性 BitBlt 到屏幕;二是把坐标轴、网格、曲线分成不同的图层,数据更新时只重绘曲线层,坐标轴和网格不动。

这个机制决定了它的性能边界:如果你的数据点每秒更新几千个,曲线层重绘的开销主要在路径构建上,而不是屏幕刷新。我一般会建议把采样数据先攒在一个环形缓冲区里,每 50ms 触发一次重绘,而不是每来一个点就刷新一次。这样既不会丢数据,也不会把 CPU 吃满。

2.2 把控件集成进对话框工程:四步走

集成 ChartCtrl 不需要改工程架构,按下面四步走就行。假设你已经有一个基于对话框的 MFC 工程,工程名用WaveDemo代称。

第一步,把控件源码目录下的ChartCtrl.h、ChartCtrl.cpp、ChartCtrlLib相关文件复制到工程目录,在 VS 的“解决方案资源管理器”里右键“头文件”和“源文件”分别添加。

第二步,在对话框头文件里包含控件头文件,并声明一个成员变量:

// WaveDemoDlg.h #include "ChartCtrl.h" // 控件主头文件 class CWaveDemoDlg : public CDialogEx { // ... 其他成员 private: CChartCtrl m_ChartCtrl; // 图表控件对象 };

第三步,在对话框的DoDataExchange里做 DDX 绑定,或者在OnInitDialog里手动创建。手动创建更灵活,适合控件是动态生成的场景:

// WaveDemoDlg.cpp BOOL CWaveDemoDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // 在对话框客户区创建一个图表控件,ID 用占位符 CRect rect; GetClientRect(&rect); rect.DeflateRect(20, 20, 20, 20); // 留出边距 if (!m_ChartCtrl.Create(this, rect, IDC_CHART_PLACEHOLDER)) { AfxMessageBox(_T("ChartCtrl 创建失败")); return FALSE; } // 初始化坐标轴和曲线,见下一节 InitChart(); return TRUE; }

第四步,在对话框的OnSize里让控件跟随窗口缩放,否则窗口拉大后图表还是原来大小:

void CWaveDemoDlg::OnSize(UINT nType, int cx, int cy) { CDialogEx::OnSize(nType, cx, cy); if (m_ChartCtrl.GetSafeHwnd()) { CRect rect(20, 20, cx - 20, cy - 20); m_ChartCtrl.MoveWindow(&rect); } }

这四步做完,编译应该能过。如果报链接错误,检查一下控件的.cpp文件是否都加进了工程,以及是否在stdafx.h或pch.h里包含了必要的 GDI+ 头文件。ChartCtrl 内部用到了 GDI+,需要在工程里初始化 GDI+,常见做法是在CWinApp::InitInstance里调用GdiplusStartup,退出时GdiplusShutdown。

2.3 坐标轴与曲线的初始化参数怎么设

控件创建好之后,默认是空的,需要手动添加坐标轴和曲线。下面这段代码初始化一个 X 轴为时间、Y 轴为电压的双轴图表:

void CWaveDemoDlg::InitChart() { // 获取 X 轴和 Y 轴对象,0 表示底部轴,1 表示左侧轴 CChartAxis* pBottomAxis = m_ChartCtrl.GetBottomAxis(); CChartAxis* pLeftAxis = m_ChartCtrl.GetLeftAxis(); // 设置轴标题 pBottomAxis->SetText(_T("时间 (s)")); pLeftAxis->SetText(_T("电压 (V)")); // 设置轴范围,X 轴 0~10 秒,Y 轴 -5~5 伏 pBottomAxis->SetMinMax(0.0, 10.0); pLeftAxis->SetMinMax(-5.0, 5.0); // 设置网格线,主刻度 1.0,次刻度 0.2 pBottomAxis->SetTickLength(5); pLeftAxis->SetTickLength(5); m_ChartCtrl.SetGridVisible(true); // 添加一条曲线,返回曲线对象指针 m_pSeries = m_ChartCtrl.AddSeries(CChartCtrl::Line); if (m_pSeries != nullptr) { m_pSeries->SetColor(RGB(0, 180, 0)); // 绿色曲线 m_pSeries->SetLineWidth(2); // 线宽 2 像素 m_pSeries->SetVisible(true); } }

参数说明:SetMinMax设的是轴的显示范围,不是数据范围,数据超出范围会被裁剪;AddSeries的参数决定曲线类型,Line是折线,还有Bar、Points等;SetLineWidth的单位是像素,太细在工控屏上看不清,太粗会盖住相邻曲线。我一般把线宽设在 2 到 3 之间,颜色避开红绿同时出现,防止色弱用户分不清。

3. 实时波形数据推送:从定时器到环形缓冲区的完整链路

3.1 数据更新频率与重绘策略的匹配

波形显示的核心矛盾是:数据来得快,重绘慢。假设采样率是 1kHz,每秒 1000 个点,如果每个点都触发一次Invalidate,界面线程基本没时间处理消息,鼠标都会卡住。正确的做法是解耦:数据采集线程只管往缓冲区写,界面线程按固定节奏读缓冲区并重绘。

常见做法是用一个环形缓冲区(ring buffer)加一个定时器。定时器周期设 50ms,也就是每秒重绘 20 次,人眼看起来已经足够流畅。每次定时器触发时,把缓冲区里新增的点追加到曲线数据里,然后调用m_ChartCtrl.RefreshCtrl()触发重绘。

// 环形缓冲区,容量 4096 个点 #define BUF_SIZE 4096 struct SamplePoint { double time; double value; }; SamplePoint g_RingBuf[BUF_SIZE]; volatile LONG g_WriteIdx = 0; // 写入位置 volatile LONG g_ReadIdx = 0; // 读取位置 // 采集线程调用:写入一个点 void PushSample(double t, double v) { LONG idx = InterlockedIncrement(&g_WriteIdx) % BUF_SIZE; g_RingBuf[idx].time = t; g_RingBuf[idx].value = v; } // 界面定时器调用:读取新增点并追加到曲线 void CWaveDemoDlg::OnTimer(UINT_PTR nIDEvent) { if (nIDEvent == TIMER_REFRESH) { LONG write = g_WriteIdx; while (g_ReadIdx != write) { LONG idx = InterlockedIncrement(&g_ReadIdx) % BUF_SIZE; m_pSeries->AddPoint(g_RingBuf[idx].time, g_RingBuf[idx].value); } // 控制曲线点数,超过 2000 点就移除最旧的 if (m_pSeries->GetPointsCount() > 2000) m_pSeries->RemovePoints(0, m_pSeries->GetPointsCount() - 2000); m_ChartCtrl.RefreshCtrl(); } CDialogEx::OnTimer(nIDEvent); }

逻辑说明:InterlockedIncrement保证多线程下索引递增的原子性;AddPoint是追加单点,如果一次要追加一批,可以用AddPoints批量接口,减少内部锁的开销;RemovePoints用来控制曲线总点数,不控制的话内存会一直涨,最后卡死。参数上,缓冲区容量和曲线保留点数要匹配:缓冲区太小会丢数据,曲线保留点数太多会拖慢重绘。我一般让曲线保留点数等于缓冲区容量的一半左右。

3.2 多通道波形的颜色与图例管理

8 通道波形如果颜色相近,根本分不清哪条是哪条。ChartCtrl 支持给每条曲线单独设颜色和图例名称:

struct ChannelConfig { COLORREF color; LPCTSTR name; }; ChannelConfig g_Channels[8] = { { RGB(220, 20, 60), _T("CH1") }, { RGB(30, 144, 255), _T("CH2") }, { RGB(50, 205, 50), _T("CH3") }, { RGB(255, 165, 0), _T("CH4") }, { RGB(148, 0, 211), _T("CH5") }, { RGB(0, 206, 209), _T("CH6") }, { RGB(255, 105, 180), _T("CH7") }, { RGB(139, 69, 19), _T("CH8") }, }; // 初始化时循环添加曲线 for (int i = 0; i < 8; ++i) { CChartSeries* pSeries = m_ChartCtrl.AddSeries(CChartCtrl::Line); pSeries->SetColor(g_Channels[i].color); pSeries->SetLineWidth(2); pSeries->SetName(g_Channels[i].name); // 图例名称 m_SeriesArray.Add(pSeries); }

图例默认显示在右上角,如果挡住波形,可以用m_ChartCtrl.SetLegendPosition挪到下方或隐藏。颜色选择上,避开纯红和纯绿同时出现,因为红绿色盲用户占比不低,工控现场又经常有老师傅,配色要考虑可读性。

3.3 暂停、缩放与游标:交互功能的实现边界

实时波形跑起来之后,用户一定会要暂停、缩放、看某个点的值。ChartCtrl 本身提供了缩放接口,但和实时刷新会冲突:缩放后如果继续自动滚动,视图会被拉回去。常见做法是加一个“暂停”按钮,暂停时停止定时器,允许用户自由缩放和拖动;恢复时重新对齐时间轴。

void CWaveDemoDlg::OnBnClickedPause() { if (m_bPaused) { SetTimer(TIMER_REFRESH, 50, nullptr); // 恢复刷新 m_bPaused = false; } else { KillTimer(TIMER_REFRESH); // 暂停刷新 m_bPaused = true; } }

游标取值需要自己处理鼠标消息,把屏幕坐标转成数据坐标,再在曲线上找最近点。ChartCtrl 没有内置游标,这部分要自己写,工作量不大但要注意坐标转换的精度。如果项目对交互要求高,建议把游标做成独立图层,不要混在曲线层里。

4. 避坑与排查:ChartCtrl 集成中最容易翻车的五个地方

4.1 编译报错“无法解析的外部符号”

现象:工程编译时提示CChartCtrl::Create或CChartCtrl::AddSeries无法解析。原因通常是控件的.cpp文件没有全部加入工程,或者 GDI+ 库没有链接。解决:检查ChartCtrl.cpp、ChartCtrlLib.cpp等源文件是否都在“源文件”过滤器下;在工程属性 → 链接器 → 输入 → 附加依赖项里加上gdiplus.lib。

4.2 波形刷新时界面闪烁

现象:定时器触发重绘时,整个对话框闪一下。原因可能是对话框本身没有开启WS_CLIPCHILDREN样式,导致父窗口重绘时把控件区域也擦了。解决:在对话框属性里勾选“Clip Children”,或者在OnInitDialog里手动加样式:

ModifyStyle(0, WS_CLIPCHILDREN);

4.3 数据点追加后曲线不显示

现象:AddPoint调用了,但界面上看不到曲线。原因通常是轴范围没设对,数据点落在显示范围之外。解决:检查SetMinMax的范围是否覆盖了数据值;如果是动态范围,需要在每次追加数据后根据最大值最小值调整轴范围,但频繁调整会导致坐标轴跳动,建议用固定范围加越界裁剪。

4.4 长时间运行后内存持续增长

现象:程序跑几个小时后内存占用从几十兆涨到几百兆。原因是没有限制曲线点数,AddPoint一直在追加,内部数组无限扩张。解决:每次追加后检查点数,超过阈值就调用RemovePoints移除最旧的数据。阈值根据屏幕像素和采样率来定,一般 2000 到 5000 点足够。

4.5 多线程直接操作控件导致崩溃

现象:采集线程里直接调用m_pSeries->AddPoint,偶尔程序崩在 GDI 内部。原因是 ChartCtrl 不是线程安全的,所有控件操作必须在界面线程完成。解决:采集线程只写环形缓冲区,界面定时器读缓冲区并更新控件。如果一定要跨线程,用PostMessage把数据指针传回界面线程处理。

5. 进阶技巧:让波形显示从“能用”到“好用”

5.1 用批量接口替代单点追加

单点AddPoint每次都会触发内部数组的扩容和锁操作,数据量大时开销明显。ChartCtrl 提供了AddPoints批量接口,一次追加一组点,内部只做一次扩容。我一般会在定时器里攒够 50 个点再批量追加,而不是来一个加一个。

// 批量追加示例 std::vector<double> times, values; // ... 从环形缓冲区读取一批数据填充 times 和 values m_pSeries->AddPoints(times.data(), values.data(), (int)times.size());

参数说明:AddPoints接受两个double数组指针和点数,数组长度必须一致。批量接口的代价是内存拷贝,所以批量大小要权衡:太小没效果,太大增加延迟。50 到 200 之间比较合适。

5.2 动态轴范围与自动滚动

实时波形通常需要 X 轴随时间滚动,只显示最近 10 秒的数据。做法是每次追加数据后,把 X 轴范围设为[latestTime - 10, latestTime],同时把超出范围的点移除。这样曲线看起来是向左滚动的,符合工控习惯。

double latestTime = m_pSeries->GetXValue(m_pSeries->GetPointsCount() - 1); m_ChartCtrl.GetBottomAxis()->SetMinMax(latestTime - 10.0, latestTime);

注意:SetMinMax会触发重绘,不要在循环里频繁调用,每次定时器刷新调一次就够了。

5.3 导出波形数据与截图

工控软件经常需要把波形保存下来做报告。ChartCtrl 没有内置导出功能,但可以自己实现:数据导出就是把曲线上的点写进 CSV,截图则是用CChartCtrl的DrawToDC画到内存 DC,再保存为 BMP。

// 导出 CSV void ExportToCsv(CChartSeries* pSeries, LPCTSTR path) { CStdioFile file; if (!file.Open(path, CFile::modeCreate | CFile::modeWrite | CFile::typeText)) return; CString line; for (int i = 0; i < pSeries->GetPointsCount(); ++i) { line.Format(_T("%.6f,%.6f\n"), pSeries->GetXValue(i), pSeries->GetYValue(i)); file.WriteString(line); } file.Close(); }

截图部分需要创建一个兼容 DC 和位图,调用控件的绘制函数,然后保存。这部分代码稍长,但逻辑不复杂,关键是记得释放 GDI 对象,否则会泄漏。

5.4 性能边界与替代方案

ChartCtrl 适合中等数据量的实时显示,大概每秒几千个点、曲线条数在 10 条以内。如果数据量再大一个数量级,或者需要 3D 显示、复杂交互,建议考虑 Direct2D 自绘或换用更专业的图表库。我自己的经验是:先用 ChartCtrl 把功能跑通,如果性能不够再针对性优化,不要一上来就追求极致性能,那样开发周期会失控。

从那以后我每次集成图表控件,都会先写一个最小可运行的波形 Demo,把数据推送、刷新、暂停、导出这四条链路走通,再往正式工程里搬。这样即使遇到玄学问题,也能快速定位是控件本身还是工程配置的锅。希望帮到你。

本文还有配套的精品资源,点击获取

相关新闻

C#实现文件批量搜索与提取:多条件筛选、递归遍历与冲突处理

C#实现文件批量搜索与提取:多条件筛选、递归遍历与冲突处理

简介&#xff1a;这是一款基于C#实现的文件批量搜索与提取工具&#xff0c;面向需要频繁整理海量文件的Windows用户与开发者。它通过读取TXT清单中的通配符条件&#xff08;如“上海*. ”“北京 .*”&#xff09;&#xff0c;在指定文件夹内递归匹配&#xff0c;并将命中文件…

2026/10/19 16:31:38 阅读更多 →
Keras核心API实战深度解析:从建模到部署的完整指南

Keras核心API实战深度解析:从建模到部署的完整指南

做深度学习模型&#xff0c;最绕不开的就是TensorFlow里的Keras。TensorFlow 2.x之后&#xff0c;Keras被正式整合为默认的高层API&#xff0c;从最简单的全连接网络到带复杂分支的多模态模型&#xff0c;几乎都能用同一套api体系解决。我接触Keras比较早&#xff0c;从1.x时代…

2026/10/19 16:31:38 阅读更多 →
DVWA文件包含漏洞实战:从目录穿越到日志注入RCE

DVWA文件包含漏洞实战:从目录穿越到日志注入RCE

做Web安全测试的朋友对DVWA这个靶场应该都不陌生。前阵子我把File Inclusion模块从Low到High又完整刷了一遍&#xff0c;发现很多细节值得记录。文件包含&#xff08;File Inclusion&#xff09;漏洞说起来并不复杂&#xff0c;本质就是让程序去加载一个由用户可控的文件路径&a…

2026/10/19 16:31:38 阅读更多 →

最新新闻

FrankenPHP Windows 原生版实测:PHP 应用服务器的本地开发新选择

FrankenPHP Windows 原生版实测:PHP 应用服务器的本地开发新选择

昨天整理电脑里的 PHP 项目时&#xff0c;顺手刷了一眼 FrankenPHP 的发布页&#xff0c;发现官方挂出了 Windows 原生的 zip 包。说实话&#xff0c;我第一反应是去看发布日期&#xff0c;确认不是旧文件——因为等这个“原生支持 Windows”的版本&#xff0c;真的等太久了。先…

2026/10/19 17:14:40 阅读更多 →
HTTP状态码从入门到实战:分类原理、避坑指南与团队规范

HTTP状态码从入门到实战:分类原理、避坑指南与团队规范

调试做多了&#xff0c;会养成一种条件反射&#xff1a;看一眼HTTP响应码&#xff0c;心里立刻分好“这锅该谁背”。HTTP响应码这件事&#xff0c;表面上就是查表背答案&#xff0c;可真做几年前后端接口开发后你会发现&#xff0c;真正值钱的不是记得熟&#xff0c;而是看到一…

2026/10/19 17:14:40 阅读更多 →
开源CLI代码审查工具:基于LLM与AST的自动化git diff分析

开源CLI代码审查工具:基于LLM与AST的自动化git diff分析

1. 项目概述&#xff1a;一个真正能落地的开源代码审查 CLI 工具“open-code-review”这个名字乍看平平无奇&#xff0c;但拆开来看——open不是指“开源”这个宽泛概念&#xff0c;而是指开放上下文、开放权限边界、开放模型接入能力&#xff1b;code review也不是走形式的 PR…

2026/10/19 17:14:40 阅读更多 →
JESD204B串行接收模块FPGA实现:从同步到仿真的完整指南

JESD204B串行接收模块FPGA实现:从同步到仿真的完整指南

简介&#xff1a;面向FPGA开发者的JESD204B高速串行接口接收模块实现代码&#xff0c;配套Vivado仿真工程&#xff0c;适合需要掌握链路同步、多通道对齐、8b/10b解码与错误检测机制的工程师学习或直接移植。压缩包共593个文件&#xff0c;约26.68MB&#xff0c;以272个txt说明…

2026/10/19 17:13:38 阅读更多 →
LangChain Tool Calling实战:从手动解析到LangGraph Agent落地

LangChain Tool Calling实战:从手动解析到LangGraph Agent落地

第一次在LangChain里跑通工具调用&#xff08;Tool Calling&#xff09;时&#xff0c;我的第一反应是&#xff1a;这不就是让模型学会"填一张调用单"吗&#xff1f;等真正把它接到业务里我才意识到&#xff0c;Tool Calling的本质是把"模型说了什么"和&qu…

2026/10/19 17:13:38 阅读更多 →
数字公关AI中台架构设计与落地实践

数字公关AI中台架构设计与落地实践

有人问我&#xff0c;数字公关是不是就是“用AI写新闻稿”&#xff1f;我说你要是这么理解&#xff0c;那这个活三个月就能干完&#xff0c;根本不需要中台。真正难的不是让模型写出一篇稿子&#xff0c;而是让舆情监测、内容生产、媒介分发、效果归因这几个环节在一套系统里持…

2026/10/19 17:13:38 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介&#xff1a;本资源为电源技术方向的学术研究文档&#xff0c;聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略&#xff0c;面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 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/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址&#xff1a; https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集&#xff0c;共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 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/19 2:54:50 阅读更多 →
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/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练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/18 12:16:16 阅读更多 →