AWTK界面开发入门:用XML构建跨平台UI的完整指南
写AWTK界面很多从传统桌面开发转过来的朋友第一反应是UI不是拖控件或者用代码new吗XML能干什么我第一次接触AWTK的XML描述时也这么想直到把第一个窗口跑起来才意识到这套“用XML搭骨架、用代码补逻辑”的方式对跨平台项目有多省事。AWTK本身是一个开源的跨平台GUI引擎支持嵌入式、桌面甚至一些轻量级场景而UI描述层大量依赖XML文件从窗口结构、控件布局到主题样式都能用XML定义。这篇东西就是给刚接触AWTK、想在XML上快速入门的开发者写的我会从XML承担的角色、基础骨架、一个完整示例、布局样式的落地再到实际开发中容易踩的坑一路讲下来。如果你是零基础也没关系我会把每个环节掰开揉碎尽量让你照着敲就能跑出东西。1. AWTK里的XML它到底在管哪块事1.1 先搞清楚AWTK和XML的分工AWTK的全称是“Toolkit AnyWhere”本质是一套自绘GUI引擎不依赖系统原生控件所以你在嵌入式Linux、桌面系统甚至模拟器上看到的是同一套渲染效果。这里有个关键点AWTK把“界面长什么样”和“界面怎么响应”分开了。界面长什么样用XML描述界面怎么响应用C或者其他语言写逻辑。换句话说XML在AWTK里是“界面描述语言”。一个窗口有哪些控件、控件放在什么位置、尺寸多大、文本内容是什么、有没有滚动条、控件之间怎么布局都可以写进XML。引擎加载XML后会解析成一棵控件树这棵树就是你在屏幕上看到的实际界面。这种分工带来的好处很明显界面调整不需要重新编译代码改完XML刷新资源就行。尤其在嵌入式项目里设备端改UI、重新烧固件是很痛苦的事XML方案可以单独把资源文件抽出来极大压缩UI迭代周期。1.2 为什么推荐从XML入手而不是纯代码搭界面AWTK也支持完全用代码来创建控件比如调用widget_create、button_create这类API一个控件一个控件地new出来。那为什么更多人建议用XML纯代码建界面最大的问题是“看不清全貌”。你从头到尾读代码脑子里要不断拼装坐标、层级、父子关系窗口复杂一点就很容易迷路。XML把层级结构用缩进和标签直接表达出来一眼看过去哪个控件在哪个容器里、谁是谁的子节点清清楚楚。第二个理由是可维护性。设计师或者产品经理改需求时拿到的往往是一张标注了位置和大小的原型图。XML可以直接照着原型图翻译x10 y20 w100 h40和标注一一对应。你不需要在代码里找半天这个控件是哪个变量创建的。第三个理由是AWTK的示例、皮肤资源和开源项目绝大多数界面都是XML描述的。你不会XML等于看不了别人的代码入门时间会成倍拉长。当然不是说代码建UI一无是处动态创建的控件、运行时临时弹出的界面仍然需要代码参与。但入门阶段先把XML吃透后面再混合使用就不会乱。2. 写XML之前必须知道的骨架窗口、控件和属性2.1 如果你连XML都没写过补三分钟基础XML本身不复杂它就是一种带标签的纯文本格式长得类似网页里的HTML。一组标签由尖括号包裹成对出现比如button.../button也可以自闭合写作button /。标签内部可以写属性属性必须用引号括起来比如button text确定 x10 y10 /。XML有几个规则必须遵守不然后面解析直接报错标签必须正确闭合不能交叉嵌套。属性值必须加引号单引号双引号都行但必须成对。根节点只能有一个整个XML文件最外层只有一个顶级标签。标签名字区分大小写Window和window不是同一个东西。AWTK的XML文件还带一个特殊的声明头类似?xml version1.0 encodingUTF-8?普通情况下加上这个声明最稳妥。2.2 AWTK的控件标签家族AWTK的XML里几乎每个控件对应一个标签名。入门阶段你只需要先记住这一小批标签控件类型典型用途window普通窗口界面最外层根节点label静态文本显示不可编辑的文字button按钮点击触发动作edit单行输入框用户输入文本mledit多行输入框长文本编辑场景progress_bar进度条显示进度百分比slider滑动条调节数值list_view列表视图纵向滚动列表row/column行容器 / 列容器做简单布局排列子控件除了这些还有dialog对话框、popup弹出窗口、combo_box下拉框等等基础玩熟了再逐个认识不迟。2.3 每个控件都有的通用属性所有控件标签都支持一组通用属性这组属性是入门最重要的内容x控件左上角相对父容器的X坐标单位是像素。y控件左上角相对父容器的Y坐标。w控件宽度。h控件高度。name控件名字代码里通过widget_lookup查找控件时就用它。text控件的显示文本按钮和标签最常用。style引用样式名具体样式定义在主题文件里。visible是否可见true或false。enable是否可用true或false。focusable是否可获得焦点键盘操作用得上。这里有个容易忽略的点text不只是按钮的文字对edit输入框来说text表示默认显示的内容对label来说text就是展示的文字。控件不同同一个属性含义略有差别具体使用时对着对应控件的文档确认一下最保险。2.4 布局容器和嵌套关系XML里控件是可以嵌套的嵌套关系决定了父子容器关系。父容器决定子控件的坐标参照系子控件的x和y是相对父容器左上角的。入门最常见的是window里面放一个row或者column再由容器去摆放内部控件。比如window column x10 y10 w200 h200 button textbtn1 / button textbtn2 / /column /windowcolumn是一个纵向排列容器它内部的子控件会自动从上到下排列不需要每个按钮手写y坐标。这对调整界面顺序特别有用中间插一个控件后面的自动下移完全不用重新算坐标。3. 从零写一个XML界面第一个窗口完整过程3.1 准备工程目录和资源路径AWTK的项目一般有固定的资源目录结构。假设你克隆了AWTK官方源码这是开源项目直接到官方仓库拉最新稳定版会看到demos目录下有一堆示例。建议你在源码根目录下建一个自己的工程目录比如my_demo然后在这个目录里创建ui子目录专门放界面XML文件。AWTK运行时通过资源管理器加载XML默认搜索路径会包括UI目录。实际开发中资源路径还分“桌面调试路径”和“嵌入式打包路径”桌面环境直接指向源码里的ui目录就行。最省事的做法是仿照官方示例把自己的XML文件丢进demos/assets/raw/ui/下然后用官方自带的工具脚本启动模拟器来预览。为什么要强调目录因为很多新手第一个坑就是代码编译没问题运行起来却白屏日志提示加载XML失败。多半是XML文件放错了目录资源管理器按默认路径找不到。3.2 写一个带输入框和按钮的登录窗口我直接贴一个最小但完整的示例你可以把它存成login.xml放在UI资源目录下?xml version1.0 encodingUTF-8? window namelogin text登录 w320 h240 label x60 y40 w200 h30 text用户名 namelabel_user / edit x60 y70 w200 h30 nameedit_user / label x60 y110 w200 h30 text密码 namelabel_pwd / edit x60 y140 w200 h30 nameedit_pwd passwordtrue / button x110 y190 w100 h30 text登录 namebtn_login / /window注意几个细节根节点是window属性name是这个窗口的逻辑名字代码里通过它打开窗口。text显示在窗口标题栏。edit里的passwordtrue表示输入掩码输入的字符显示为星号登录界面必备。每个控件我都显式写了name这是为了后面代码查找控件做准备。没有name的控件代码里基本找不到它可以理解为匿名控件。这就是一个最简单的UI骨架两个文本标签、两个输入框、一个按钮坐标都是相对窗口左上角排的。3.3 运行并让它显示出来AWTK桌面模拟器运行需要额外的启动逻辑。一般来说官方示例在demos里有一个入口会在程序启动时加载指定XML。最直接的验证方式是用AWTK自带的设计工具或者预览程序选择一个XML然后直接打开。如果你自己写C代码加载核心逻辑非常短/* 这是伪代码思路实际需要引入对应头文件并初始化AWTK */ tk_init(tk_get_argc(), tk_get_argv(), NULL, NULL); widget_t* win window_open(login); tk_run();window_open的参数是XML文件名去掉.xml后缀。AWTK会去默认UI目录寻找login.xml解析、构建控件树、显示窗口然后进入主循环。很多新手会卡在window_open返回NULL这一步。最常见的原因是XML文件不在搜索路径里或者XML格式有问题导致解析失败。遇到返回NULL时优先查终端里的日志AWTK日志一般会明确告诉你文件加载失败还是解析报错。3.4 给按钮接上点击逻辑光有界面不响应等于一张截图。XML定义好界面后需要在代码里给按钮注册事件。核心思路是用widget_lookup按名字找到按钮然后绑定点击回调。widget_t* btn widget_lookup(win, btn_login, TRUE); widget_on(btn, EVT_CLICK, on_login_click, win);回调函数里可以读取输入框内容、做逻辑判断、跳转窗口等。这里体现AWTK的典型开发流程XML负责静态结构代码负责动态交互。两条腿一起走界面和逻辑互不干扰。4. 布局、样式、主题把界面弄好看再往深走4.1 坐标硬排和简单容器布局怎么选第一个示例我用了硬坐标每个控件手动指定x、y、w、h这是最容易理解但也最笨的方式。窗口尺寸一旦变化硬坐标控件位置不会自动适应适配就变成一场噩梦。稍微进阶一点应该用布局容器。row是水平排列子控件column是垂直排列子控件它们加上x、y、w、h后内部子控件可以不写坐标由容器自动排。比如window namelayout_demo w300 h200 row x10 y50 w280 h40 children_layoutdefault(h40, gap10) button text确认 / button text取消 / /row /windowchildren_layout是AWTK比较核心的布局属性它的写法类似函数调用default(h40, gap10)表示子控件高度固定40像素子控件之间的间距10像素。配合row容器两个按钮自动横向排开窗口宽度变了AWTK会按布局规则重新计算位置。这个设计理念对做多分辨率适配特别有价值窗口尺寸变化时布局容器自动重新排列控件省去一大半适配工作量。硬坐标适合原型验证生产环境尽量用容器布局。4.2 样式style把默认控件换成自己的皮肤AWTK控件自带默认风格但真实项目里肯定要改字体、背景色、圆角、按下效果。这些都可以通过style属性指向主题文件中的样式定义。在XML里给控件挂样式button text登录 stylegreen_btn /然后在主题XML里定义green_btn。主题文件一般叫default.xml放在styles目录下。大致的结构是style namegreen_btn normal bg_colorgreen fg_colorwhite / pressed bg_colordarkgreen fg_colorwhite / over bg_colorlightgreen fg_colorblack / /stylenormal、pressed、over分别对应按钮普通状态、按下状态、鼠标悬停状态。AWTK渲染引擎会根据控件状态自动切换样式。样式也支持圆角、边框、字体大小等属性更高级的还能放图片背景。但入门你不用记太多先理解这个机制XML里的style只是名字真正的视觉参数在主题文件里。换皮肤时连控件代码都不用动只要换主题文件就行这也是XML方案比代码建UI舒服的地方之一。4.3 主题文件default.xml的定位主题XML经常被新手和界面XML搞混。界面XML描述结构主题XML描述样式两者是不同维度的资源。AWTK运行时默认加载default.xml作为主题界面XML里通过stylexxx去主题里找对应的style节点。如果某个控件的样式名在主题里找不到AWTK会退回到内置默认样式不会崩溃但你的自定义效果就丢了。所以改了样式没反应时第一反应应该是检查主题XML里有没有这个名字以及语法是否正确。主题文件还支持全局字体定义、图片资源的别名映射等属于进阶内容。入门阶段你先掌握“界面结构XML 主题样式XML”的双层体系后面做皮肤定制时就轻车熟路了。5. 实际写XML时我踩过的坑和排查思路5.1 白屏问题根节点选错是最隐蔽的有一次我把一个界面根节点写成了view而不是window结果窗口能打开但里面什么都没有日志也没有报错。原因是view是一个普通容器控件不承载窗口标题栏和窗口级行为作为根节点时虽然创建成功却没有窗口应有的尺寸适配逻辑内容全部跑到屏幕外面去了。排查思路很简单窗口级界面用window弹层用dialog或popup普通容器只能做中间节点。如果你的界面运行后一片空白优先检查根节点标签是否用对。5.2 坐标单位搞错不是百分比也不是dpAWTK的坐标单位就是像素这一点和很多移动端开发者的直觉不同。有人习惯写x50%AWTK根本不认识有人以为是dp密度像素在高分屏上缩放后元素全部错位。还有一个反直觉的规则默认坐标是相对父容器的但如果你给子控件设置了类似self_layout的高级属性坐标系含义会变。入门阶段尽量不要混用先全部用普通x、y等遇到具体适配需求再研究高级布局。5.3 属性名拼写和布尔值写法AWTK的属性很多是完整的英文单词比如focusable、visible、enable。拼写一变属性就静默失效引擎不会报错。更坑的是布尔值AWTK的XML解析支持true和false小写不能用TRUE或者1去试。我现在遇到UI表现和预期不符的情况第一步就是打开XML文件逐个属性核对拼写。很多“奇怪的问题”最后都是属性的锅不是引擎的锅。5.4 XML解析报错的定位方法解析报错时AWTK日志会给出文件名和行号但行号不一定精确特别是属性值里有特殊字符时。经验法则是注释掉最近改动的那一行逐步缩小范围。还有一个真实场景文本内容里包含中文引号或者符号时XML解析会失败。比如按钮文字想显示“保存退出”必须写成amp;。这个转义规则和HTML一致记不住的话凡是看到XML解析报错优先检查文本内容里有没有、、这些保留字符。5.5 修改XML后界面没变化缓存问题AWTK桌面模拟器对资源有缓存直接改XML文件名、文件名改了但内容没变或者文件时间戳没变化时模拟器可能加载的是旧缓存。遇到UI死活不刷新先试试清掉运行目录下的缓存文件再重新启动。嵌入式设备上这个问题更隐蔽因为资源经常被打包到固件镜像里改了XML不重新打包资源等于没改。我自己的习惯是在UI目录下新建一个独立的测试窗口每次改完只刷新单窗口确认无误后再合入正式界面。这样能省掉大量“改错了但不知道错在哪”的时间。6. 入门之后XML只是入口后面还有这些事6.1 代码和XML的配合边界把XML入门后你会慢慢发现一个开发节奏静态界面全部交给XML动态部分交给代码。什么算动态运行时根据数据变化的控件内容、临时创建的浮层、需要频繁增删的列表项这些用代码创建更合适。XML适合定义“模板”代码适合处理“实例”。比如一个列表界面XML只放一个空的list_view里面的列表项在收到网络数据后用代码动态create并填充。这样XML保持精简数据又灵活。反之如果列表项都写死在XML里数据一变就要重新加载界面性能浪费不说代码也很别扭。6.2 动态更新界面改属性比重建窗口更省事代码里可以通过widget_set_text改文本、widget_move_resize改位置大小、widget_set_enable切换可用状态。更新属性比整个窗口重建高效得多。XML定义了初始状态代码负责后续状态迁移这两者配合顺了开发效率会有明显提升。举个例子登录失败时让界面上显示错误信息widget_t* label widget_lookup(win, label_msg, TRUE); widget_set_text_utf8(label, 用户名或密码错误);不用新建窗口不用重载XML一行代码就把界面从初始状态切到了错误状态。理解了这一点你才算真正明白为什么AWTK要把UI描述交给XML——它把界面抽象成一组可查询、可修改的属性集合XML是这套属性集合的静态快照代码是动态操作。6.3 给入门者的一条学习路线建议AWTK的XML入门不要贪多。我的建议是找一个最简单的官方示例先把window、label、button三个控件组合起来跑通再逐步加edit、布局容器、样式。每加一个控件就去看一次对应控件的属性文档理解每一个属性到底控制什么。等你能够独立用XML做一个带输入框、按钮、列表的界面并且能在代码里响应按钮事件、动态更新控件内容这门“XML篇”就算真正毕业了。再往后主题定制、自定义控件、动画、多国语言资源、窗口切换动画都是在这个基础上的自然延伸。我至今还留着当初跑通的第一个AWTK登录窗口那个界面丑得不行但它教会我的不是某个控件怎么用而是“XML描述结构、代码驱动行为”这套思维。后面再做复杂的界面我都在下意识地问自己这一块是应该写进XML还是应该留给代码想清楚了UI开发的大半问题也就不是问题了。

相关新闻

智能制造落地指南:AI视觉质检与流程预测实战

智能制造落地指南:AI视觉质检与流程预测实战

简介:《面向人工智能的智能制造解决方案》演示文稿,聚焦制造业在价格波动、劳动力短缺、供应链成本优化等挑战下,如何借助数字化与人工智能实现效率提升和业务重塑,适合制造业管理者、数字化转型顾问及相关技术人员参考。资源为单…

2026/10/13 1:12:53 阅读更多 →
X-FAB埃尔福特新洁净室动工:欧洲MEMS与光子学代工产能扩张的战略解析

X-FAB埃尔福特新洁净室动工:欧洲MEMS与光子学代工产能扩张的战略解析

X-FAB埃尔福特新洁净室动工:欧洲MEMS与光子学代工产能扩张的战略解析 一、项目背景与战略定位 X-FAB Silicon Foundries(以下简称“X-FAB”)已在德国埃尔福特(Erfurt)基地正式动工建设新的洁净室设施。此举标志着该公司在欧洲扩大MEMS(微机电系统)和光子学晶圆制造产能…

2026/10/13 1:12:53 阅读更多 →
动态数据分析表从设计到落地:Excel、BI与Python方案全解析

动态数据分析表从设计到落地:Excel、BI与Python方案全解析

/* 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 1:12:53 阅读更多 →

最新新闻

PS5通用调校指南:从HDR发灰、下载慢到手柄断连的排查与优化

PS5通用调校指南:从HDR发灰、下载慢到手柄断连的排查与优化

最近一位朋友新入手了PS5,连着问了我好几个问题:电视开HDR之后画面发灰,下载一个游戏等了一夜还没好,手柄玩到一半断连,重连又要重新匹配。我一边远程指导一边发现,这些疑难杂症其实跟“哪一台PS5”没什么关…

2026/10/13 3:19:47 阅读更多 →
接口自动化测试实战:Excel用例管理+unittest+xlrd+xlsxwriter

接口自动化测试实战:Excel用例管理+unittest+xlrd+xlsxwriter

/* 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 3:19:47 阅读更多 →
AnyPS5实战:基于官方链路的PS5游戏串流全攻略

AnyPS5实战:基于官方链路的PS5游戏串流全攻略

如果你家里的 PS5 只能老老实实待在客厅电视下面,那这台机器一大半的潜力其实都没被用上。AnyPS5 是我这段时间集中折腾的一个项目,思路特别直接:把 PS5 的画面和操作,通过游戏串流的方式,送到你手边任何一块屏幕上——…

2026/10/13 3:19:47 阅读更多 →
PMI参数的解读与应用分析

PMI参数的解读与应用分析

PMI是宏观经济的重要指标,这里尝试对PMI参数进行解读和分析。 1 定义与特征 1.1 定义 采购经理指数(PMI)通过对企业采购经理的月度问卷调查结果统计汇总、编制而成的指数, 涵盖企业采购、生产、流通等各个环节,包括制造业和非制造业领域&…

2026/10/13 3:19:47 阅读更多 →
Simulink风光储并网系统建模与协调控制策略详解

Simulink风光储并网系统建模与协调控制策略详解

1. 项目概述与整体系统方案选择风电和光伏是当前电力系统中发展最快的两类清洁能源,但两者的出力特性完全不同——风电随风速波动,光伏则受辐照度和温度制约,两者叠加后仍然存在天然间歇性。储能系统的加入就是用来弥补这种波动,把…

2026/10/13 3:19:47 阅读更多 →
小白程序员必备:收藏!从零开始掌握 Codex 大模型核心技术

小白程序员必备:收藏!从零开始掌握 Codex 大模型核心技术

本文深入解析 Codex 大模型的六层架构,涵盖模型、Runtime、Context、Tool、Sandbox 和 Environment 的功能与关系。通过分析 Agent Loop 的工作原理,揭示 Token 的计量方式以及 Context Window 与 Memory 的关联。文章还探讨了长任务中出现的“忘记”现象…

2026/10/13 3:18:47 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 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/12 21:05:09 阅读更多 →
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/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练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 阅读更多 →