MFC CSplitterWnd实现三窗格界面:原理、架构与实战技巧
1. 项目概述为什么需要三窗格界面在开发桌面应用程序尤其是像代码编辑器、数据管理工具或资源管理器这类复杂工具时单一视图往往捉襟见肘。想象一下你正在开发一个类似Visual Studio的IDE左边是项目文件树中间是代码编辑区右边是属性面板或调试信息窗口。如果这三个区域都挤在一个窗口里用户要么需要频繁切换标签页要么就得忍受混乱的布局。这时一个稳定、可自由调整、逻辑清晰的多窗格界面就成了提升用户体验和生产力的关键。VC这里特指基于MFC框架的C开发作为Windows桌面开发的经典技术栈其内置的CSplitterWnd类是实现这类拆分窗口的利器。但官方文档往往只告诉你“是什么”和“怎么用”对于如何构建一个左、中、右三个固定窗格的复杂布局以及其中可能遇到的坑却鲜有详述。今天我就结合自己十多年的客户端开发经验来拆解如何用CSplitterWnd稳健地实现一个三窗格界面并分享那些只有踩过坑才知道的实战技巧。2. 核心思路与CSplitterWnd深度解析在动手之前我们必须吃透CSplitterWnd的核心机制。它本质上是一个窗口容器负责管理其内部子窗口即窗格的布局和大小调整。根据微软的TN029技术文档它支持两种模式静态拆分和动态拆分。我们的三窗格布局通常属于静态拆分。2.1 静态拆分 vs. 动态拆分静态拆分在创建拆分器窗口时就一次性创建好所有窗格。窗格的数量和顺序是固定的用户只能拖动分割条来调整各窗格的大小但不能动态创建或删除窗格。Visual Studio的资源编辑器、Windows文件管理器的左右分栏就是典型例子。这种模式适合布局固定的多视图应用。动态拆分初始只有一个窗格用户通过菜单或分割框主动拆分可以动态创建新的窗格视图。像老版本的Excel或Word允许你将同一个文档拆分成多个视图进行对照。这种模式更灵活但逻辑也更复杂。对于“左中右三窗格”这种明确需求静态拆分是我们的不二之选。它的行为可预测性能开销小实现起来也更直接。2.2 理解窗格、行、列与拆分条CSplitterWnd使用一个行和列的网格模型来管理窗格。创建一个2行1列的拆分器你会得到上下两个窗格创建1行2列则是左右两个窗格。那么左中右三个窗格是1行3列吗理论上是的但这里有一个关键点一个CSplitterWnd实例只能管理一个方向行或列的拆分。这意味着如果你直接创建一个1行3列的CSplitterWnd你只能得到两条垂直分割条管理三个垂直排列的窗格。这虽然也是“左中右”但如果你还希望某个窗格比如中间的编辑区内部能再进行水平拆分例如上方代码区下方输出窗口单个CSplitterWnd就无能为力了。因此实现复杂嵌套布局的黄金法则是嵌套使用多个CSplitterWnd对象。这也是实现我们目标架构的核心。3. 架构设计与实现步骤我们的目标是主窗口客户区被分为左、中、右三个主要区域。其中中间区域可能还需要进一步拆分为上下两个部分例如代码编辑区和输出控制台。下面我们来一步步构建。3.1 第一步规划整体布局我们采用两级嵌套拆分器一级拆分器水平负责将主窗口客户区划分为左和右两个大区域。我们称它为m_wndHSplitter。二级拆分器嵌套在右侧将第一步得到的右侧区域再次垂直拆分为中和右两个区域。我们称它为m_wndVSplitter。三级拆分器可选嵌套在中间如果需要将中间区域再水平拆分如上文所述则在m_wndVSplitter的左侧窗格内再创建一个水平拆分器。这样通过两个拆分器的嵌套我们就得到了左、中、右三个窗格。如果需要中间窗格还能继续复杂化。3.2 第二步在框架窗口中创建拆分器通常我们在主框架窗口类CMainFrame派生自CFrameWnd或CMDIFrameWnd的OnCreateClient成员函数中创建拆分器。这是MFC框架推荐的初始化位置。BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) { // 1. 创建一级水平拆分器1行2列 if (!m_wndHSplitter.CreateStatic(this, 1, 2)) // 将主窗口拆分为1行2列 { TRACE0(Failed to create horizontal splitter\n); return FALSE; } // 2. 在一级拆分器的第0列左侧创建视图窗格 // 假设CLeftView是你的左侧树形视图或文件列表视图类 if (!m_wndHSplitter.CreateView(0, 0, RUNTIME_CLASS(CLeftView), CSize(200, 100), pContext)) { TRACE0(Failed to create left pane view\n); return FALSE; } // 3. 在一级拆分器的第1列右侧创建二级垂直拆分器 // 注意这里创建的不是视图而是另一个CSplitterWnd对象 if (!m_wndVSplitter.CreateStatic(m_wndHSplitter, // 父窗口是水平拆分器 2, 1, // 将右侧区域拆分为2行1列上下结构 WS_CHILD | WS_VISIBLE | WS_BORDER, // 样式通常需要WS_BORDER来看到分割条 m_wndHSplitter.IdFromRowCol(0, 1))) // 关键获取右侧窗格的ID { TRACE0(Failed to create nested vertical splitter\n); return FALSE; } // 4. 在二级拆分器的第0行第0列上侧即“中间”主区域创建视图 // 假设CCenterView是你的主编辑区视图类 if (!m_wndVSplitter.CreateView(0, 0, RUNTIME_CLASS(CCenterView), CSize(0, 0), pContext)) { TRACE0(Failed to create center pane view\n); return FALSE; } // 5. 在二级拆分器的第1行第0列下侧即“右边”区域创建视图 // 假设CRightView是你的属性面板或输出窗口视图类 if (!m_wndVSplitter.CreateView(1, 0, RUNTIME_CLASS(CRightView), CSize(0, 0), pContext)) { TRACE0(Failed to create right pane view\n); return FALSE; } // 设置初始窗格大小可选在下一步详细说明 m_wndHSplitter.SetColumnInfo(0, 200, 100); // 左侧窗格初始宽度200最小宽度100 m_wndHSplitter.SetColumnInfo(1, 600, 300); // 右侧区域初始宽度600最小宽度300 m_wndVSplitter.SetRowInfo(0, 400, 200); // 中间窗格初始高度400最小高度200 m_wndVSplitter.SetRowInfo(1, 200, 100); // 底部窗格初始高度200最小高度100 m_wndHSplitter.RecalcLayout(); m_wndVSplitter.RecalcLayout(); return TRUE; // 返回TRUE表示我们已自行创建客户区框架不必再处理 }关键点解析CreateStatic参数第一个参数是父窗口指针。嵌套时子拆分器的父窗口必须是容纳它的那个拆分器窗格通过IdFromRowCol获取的ID对应的窗口。IdFromRowCol这是嵌套拆分器的灵魂。它获取指定行、列位置的窗格的子窗口ID。将这个ID作为子拆分器创建时的nID参数MFC的消息路由和焦点管理才能正确工作。CreateView用于在拆分器中创建视图窗格。pContext参数包含了文档模板信息对于文档/视图架构至关重要。窗格不一定非得是CView虽然例子中用了CView派生类但CreateView内部通过pContext-m_pNewViewClass创建。如果你想放入一个普通的CWnd派生控件如CListCtrl需要更复杂的处理通常重写CreateView或使用Create方法。一个更简单的替代方案是创建一个空的CView派生类在其OnCreate中创建你需要的控件作为子窗口。3.3 第三步精细控制窗格尺寸与行为创建好只是第一步让界面好用还得精细调校。3.3.1 设置初始和最小尺寸使用SetRowInfo和SetColumnInfo来控制行高/列宽。函数原型void SetRowInfo(int row, int cyIdeal, int cyMin);row: 行索引。cyIdeal: 理想高度像素。系统会尽量满足但受限于总空间。cyMin: 最小高度。用户无法将分割条拖拽到使该行高度小于此值。调用时机在OnCreateClient中创建所有窗格后调用RecalcLayout()之前设置。// 设置水平拆分器的列信息 m_wndHSplitter.SetColumnInfo(0, 250, 150); // 左栏理想250px最小150px m_wndHSplitter.SetColumnInfo(1, -1, 300); // 右栏理想值-1表示剩余空间最小300px // 设置垂直拆分器的行信息 m_wndVSplitter.SetRowInfo(0, -1, 200); // 上栏中间主区域占满剩余空间最小200px m_wndVSplitter.SetRowInfo(1, 150, 80); // 下栏右下方区域理想150px最小80px // 必须调用使设置生效 m_wndHSplitter.RecalcLayout(); m_wndVSplitter.RecalcLayout();实操心得 将某一栏的理想尺寸设为-1是一个常用技巧表示“占据所有剩余空间”。这能确保当主窗口大小变化时核心工作区如中间的编辑区能自动填充而侧边栏保持相对固定或按比例调整。3.3.2 保存与恢复布局状态一个专业的应用应该记住用户调整后的窗格大小。这可以通过在框架窗口中序列化拆分器状态来实现。// 在CMainFrame类中添加成员变量保存比例或直接保存像素值 int m_nLeftPaneWidth; int m_nBottomPaneHeight; // 在窗口销毁时如OnDestroy或OnClose保存 void CMainFrame::OnDestroy() { CRect rect; m_wndHSplitter.GetColumnInfo(0, m_nLeftPaneWidth, m_nLeftPaneMin); m_wndVSplitter.GetRowInfo(1, m_nBottomPaneHeight, m_nBottomPaneMin); // 将m_nLeftPaneWidth, m_nBottomPaneHeight保存到注册表或配置文件 CFrameWnd::OnDestroy(); } // 在窗口创建后OnCreateClient末尾或首次显示时OnShowWindow恢复 BOOL CMainFrame::OnCreateClient(...) { // ... 创建拆分器和视图的代码 ... // 从配置读取保存的值 m_nLeftPaneWidth LoadFromConfig(LeftPaneWidth, 250); m_nBottomPaneHeight LoadFromConfig(BottomPaneHeight, 150); // 应用保存的尺寸 m_wndHSplitter.SetColumnInfo(0, m_nLeftPaneWidth, 100); // 计算右侧初始宽度总宽度-左侧宽度-分割条宽度这里简化处理 m_wndHSplitter.SetColumnInfo(1, -1, 300); m_wndVSplitter.SetRowInfo(1, m_nBottomPaneHeight, 80); m_wndVSplitter.SetRowInfo(0, -1, 200); // 中间区域占据剩余空间 m_wndHSplitter.RecalcLayout(); m_wndVSplitter.RecalcLayout(); return TRUE; }4. 高级技巧与避坑指南掌握了基础创建和尺寸控制下面这些经验能让你避开90%的坑并实现更高级的功能。4.1 处理窗格内的滚动条同步当左右或上下的窗格内容需要联动滚动时例如左边是大纲右边是文档滚动文档时大纲高亮跟随CSplitterWnd支持共享滚动条。在创建拆分器时指定WS_HSCROLL或WS_VSCROLL样式即可。// 创建带垂直共享滚动条的水平拆分器 if (!m_wndHSplitter.CreateStatic(this, 1, 2, WS_CHILD | WS_VISIBLE | WS_VSCROLL)) { // ... error handling }重要限制共享滚动条机制是为CScrollView或自行处理WM_VSCROLL/WM_HSCROLL消息的CView派生类设计的。如果窗格内是普通控件如CEdit滚动条可能无法正确同步。此时你需要手动在窗格视图类中处理滚动消息并调用CSplitterWnd的SetScrollPos等函数来同步其他窗格。4.2 自定义分割条外观默认的分割条就是一个细线拖动时是一个虚线框。你可以通过重写CSplitterWnd的虚函数来定制它们。class CMySplitterWnd : public CSplitterWnd { public: virtual void OnDrawSplitter(CDC* pDC, ESplitType nType, const CRect rect); virtual void OnInvertTracker(const CRect rect); }; void CMySplitterWnd::OnDrawSplitter(CDC* pDC, ESplitType nType, const CRect rect) { // nType 可以是 splitBox, splitBar, splitIntersection if (nType splitBar) { // 自定义分割条绘制例如画一个渐变色的条 CBrush br(RGB(220, 230, 240)); pDC-FillRect(rect, br); // 画两条细边线 pDC-Draw3dRect(rect, RGB(180, 190, 200), RGB(255, 255, 255)); } else { // 其他部分使用默认绘制 CSplitterWnd::OnDrawSplitter(pDC, nType, rect); } } void CMySplitterWnd::OnInvertTracker(const CRect rect) { // 自定义拖动时的跟踪矩形例如画一个实心半透明矩形 CWindowDC dc(this); CBrush br(HS_DIAGCROSS, RGB(0, 0, 255)); // 蓝色斜线画刷 dc.FrameRect(rect, br); }然后在CMainFrame中使用CMySplitterWnd类型声明m_wndHSplitter和m_wndVSplitter即可。4.3 动态显示/隐藏窗格有时我们需要临时隐藏某个窗格比如关闭右侧属性面板。CSplitterWnd没有直接的ShowPane函数但可以通过设置其最小尺寸为0并调整其他窗格尺寸来实现“隐藏”。void CMainFrame::ToggleRightPane(bool bShow) { int nCurSize, nMinSize; m_wndHSplitter.GetColumnInfo(1, nCurSize, nMinSize); if (bShow) { // 显示恢复之前保存的宽度或设置一个默认宽度 m_wndHSplitter.SetColumnInfo(1, m_nSavedRightPaneWidth, 100); } else { // 隐藏记录当前宽度然后将理想和最小宽度都设为0 m_nSavedRightPaneWidth nCurSize; m_wndHSplitter.SetColumnInfo(1, 0, 0); } m_wndHSplitter.RecalcLayout(); // 需要重画客户区 m_wndHSplitter.RedrawWindow(); }更彻底的方法是调用ShowWindow(SW_HIDE)隐藏整个窗格视图但这需要你同时处理拆分条的逻辑并重写CSplitterWnd的布局计算更为复杂。上述“最小尺寸设为0”的方法在大多数情况下是简单有效的。4.4 处理键盘导航与焦点在多窗格界面中用户期望能用Tab键或快捷键如F6在窗格间切换焦点。MFC为CView提供了ID_NEXT_PANE和ID_PREV_PANE这两个默认命令ID。你可以在框架窗口的加速键表或菜单中绑定它们例如将CtrlTab映射到ID_NEXT_PANE。CSplitterWnd与CView协作会自动处理这些命令将焦点在相邻窗格间循环移动。如果你的窗格不是CView或者需要自定义导航逻辑可以重写框架窗口的ActivateNext或相关函数。5. 常见问题与实战排查即使按照步骤来也难免会遇到问题。这里记录几个我踩过的典型深坑和解决方法。5.1 问题嵌套拆分器创建失败程序断言或崩溃可能原因1嵌套拆分器创建时CreateStatic的父窗口参数或ID参数错误。必须使用父拆分器窗格的ID通过IdFromRowCol获取。排查检查CreateStatic调用。确保第一个参数父窗口指向了正确的父拆分器对象指针第四个参数nID使用了父拆分器.IdFromRowCol(row, col)。可能原因2在OnCreateClient中创建顺序混乱。必须先创建父拆分器及其窗格才能获取其子窗格ID用于创建嵌套拆分器。排查严格按照“先外后内先创建后获取ID”的顺序编写代码。5.2 问题分割条拖动不流畅或窗格内容闪烁严重可能原因窗格视图的OnDraw或OnPaint函数绘制效率低下或者没有正确处理背景擦除。解决方案优化绘制在视图的OnDraw中只绘制必要区域避免全屏重绘。对于复杂视图考虑使用双缓冲。禁止背景擦除在视图类中重写OnEraseBkgnd函数并直接返回TRUE让OnDraw完全负责绘制可以避免拖动时的闪烁。BOOL CMyView::OnEraseBkgnd(CDC* pDC) { return TRUE; // 告诉系统背景已擦除 }设置窗口扩展样式在视图创建前尝试添加WS_EX_COMPOSITED扩展样式Windows XP及以上它可以使用双缓冲技术合成整个窗口有效减少闪烁但可能有轻微性能影响。5.3 问题窗格内的控件如编辑框无法正常接收焦点或鼠标消息可能原因拆分器窗口和窗格视图之间的消息路由或父子窗口关系出现问题。特别是如果你在窗格视图内手动创建了控件。解决方案确保控件是以窗格视图CYourPaneView为父窗口创建的而不是以主框架或拆分器为父窗口。在窗格视图的OnCreate函数中创建控件并确保传递正确的父窗口句柄this-m_hWnd。如果问题依旧检查是否在某个地方错误地禁用了控件或视图。可以在Spy等工具中查看窗口的父子关系和样式。5.4 问题程序退出时调试输出显示有内存泄漏CWnd对象可能原因MFC的CSplitterWnd在销毁时会自动销毁其管理的所有窗格视图。但如果你的窗格视图内动态创建了其他对象如CImageList,HBITMAP等并且没有在视图的析构函数中正确释放就会报告泄漏。解决方案仔细检查每个窗格视图类CLeftView,CCenterView等的析构函数确保释放了所有动态分配的资源。对于MFC对象使用DeleteObject()或Delete()对于GDI对象使用DeleteObject()对于纯指针使用delete。5.5 问题在高DPI显示器上分割条位置和窗格尺寸错乱可能原因代码中使用了硬编码的像素值来设置初始尺寸或最小尺寸没有考虑DPI缩放。解决方案对于现代Windows应用支持Per-Monitor DPI V2应该使用与DPI无关的单元。将像素值转换为DPI感知值使用MulDiv函数或者通过GetDeviceCaps获取逻辑DPI进行计算。int GetDPIScaledSize(int nBaseSize, CWnd* pWnd) { HDC hDC ::GetDC(pWnd-GetSafeHwnd()); int dpiX GetDeviceCaps(hDC, LOGPIXELSX); ::ReleaseDC(pWnd-GetSafeHwnd(), hDC); // 假设nBaseSize是在96DPI下的设计尺寸 return MulDiv(nBaseSize, dpiX, 96); }在OnCreateClient中调用用GetDPIScaledSize(200, this)代替硬编码的200。处理DPI变化如果支持运行时DPI更改还需要响应WM_DPICHANGED消息并在此消息处理中重新计算和设置所有窗格的尺寸。实现一个稳定、美观、易用的三窗格界面远不止调用几个API那么简单。它涉及到对MFC窗口管理机制的深刻理解以及对用户体验细节的持续打磨。从规划布局、嵌套拆分器到控制尺寸、保存状态再到处理焦点、优化绘制每一步都需要仔细考量。希望这篇结合了原理、步骤和大量实战经验的分享能帮你绕过我当年踩过的那些坑更高效地构建出强大的桌面应用界面。记住好的界面是沉默的助手它不打扰用户却在用户需要时提供恰到好处的支持。

相关新闻

深入解析Unreal引擎Binned2内存分配器:原理、优化与实战调试

深入解析Unreal引擎Binned2内存分配器:原理、优化与实战调试

1. 项目概述:深入Unreal引擎的内存腹地 如果你在开发大型Unreal项目时,曾被编辑器吃掉十几个G内存的场景震撼过,或者为打包后游戏在移动设备上频繁崩溃而头疼,那么你很可能已经触及了引擎内存管理的冰山一角。内存,这个…

2026/10/2 13:24:15 阅读更多 →
DSPE-PEG-FITC-IgG复合物的构建与应用解析

DSPE-PEG-FITC-IgG复合物的构建与应用解析

1. 理解DSPE-PEG-FITC-IgG复合物的基本构成 DSPE-PEG-FITC-IgG这个看似复杂的名称实际上由四个关键部分组成,每个部分都在生物医学应用中扮演着独特角色。让我们拆解这个分子复合物的结构,就像拆解一台精密仪器的各个组件一样。 二硬脂酰磷脂酰乙醇胺&a…

2026/10/15 14:58:11 阅读更多 →
KKS-HF_Patch:Koikatsu Sunshine终极增强补丁安装与使用指南

KKS-HF_Patch:Koikatsu Sunshine终极增强补丁安装与使用指南

KKS-HF_Patch:Koikatsu Sunshine终极增强补丁安装与使用指南 【免费下载链接】KKS-HF_Patch Automatically translate, uncensor and update Koikatsu Sunshine! 项目地址: https://gitcode.com/gh_mirrors/kk/KKS-HF_Patch KKS-HF_Patch是为《Koikatsu Suns…

2026/10/13 16:32:20 阅读更多 →

最新新闻

SAP PP与CO集成配置指南:生产订单成本核算与月末结账要点

SAP PP与CO集成配置指南:生产订单成本核算与月末结账要点

做SAP实施这些年,PP(生产计划)和CO(成本控制)的交接地带一直是项目里最容易翻车的区域。生产部门觉得订单是计划问题,财务觉得订单是钱的问题,但生产订单在系统里却同时承载着物料消耗、工时确认…

2026/10/15 18:33:47 阅读更多 →
如何5分钟开启AI学习之旅:ai-learning-roadmaps环境搭建新手快速入门教程

如何5分钟开启AI学习之旅:ai-learning-roadmaps环境搭建新手快速入门教程

【免费下载链接】ai-learning-roadmaps A complete, structured hub for learning Artificial Intelligence — covering AI, Machine Learning, Deep Learning, and Data Science with books, roadmaps, and curated resources from beginner to advanced. 项目地址&#xff1…

2026/10/15 18:33:47 阅读更多 →
Java volatile原理深度解析:可见性、有序性与非原子性

Java volatile原理深度解析:可见性、有序性与非原子性

1. 为什么“volatile”这个词在代码里总被当成“开关”用,却没人真懂它拧的是哪颗螺丝?刚入行那会儿,我看到同事在多线程代码里加volatile,就像给电灯拉了根明线——“这灯肯定能亮,一拉就亮,不卡顿”。后来…

2026/10/15 18:33:47 阅读更多 →
智能吸虫塔实战:从硬件选型到YOLOv8昆虫识别与田间部署

智能吸虫塔实战:从硬件选型到YOLOv8昆虫识别与田间部署

我们站了四十多分钟,就为了看完一株棉花顶叶背后的“虫口账”。这是我做植保这几年最累也是最无奈的事情:靠人力弯着腰数虫,记录本写满一整页,可能还不如一小块麦田里实际虫量的零头。后来我把目光转向了智能吸虫塔——这个名字听…

2026/10/15 18:33:47 阅读更多 →
Principia的负责任的解释清单:6条必须知道的限制,别让AI规则变成假发现

Principia的负责任的解释清单:6条必须知道的限制,别让AI规则变成假发现

【免费下载链接】Principia Principia extracts reusable principles, composes those principles into traceable research ideas, and helps researchers inspect why an idea may be worth testing. 项目地址: https://gitcode.com/gh_mirrors/princi/Principia …

2026/10/15 18:33:47 阅读更多 →
Hadoop与Spark选型指南:从性能对比到落地实践

Hadoop与Spark选型指南:从性能对比到落地实践

1. 先聊两句:为什么总有人拿他俩做对比但凡接触过大数据,几乎都绕不开同一个问题:Hadoop和Spark到底选哪个?我在不少技术群里见过类似的争论,有人觉得Spark快,所以Spark一定更好;也有人觉得Hado…

2026/10/15 18:32:46 阅读更多 →

日新闻

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/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

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

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

2026/10/14 16:30:29 阅读更多 →
影刀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/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/15 9:49:14 阅读更多 →