MITK/BlueBerry 插件机制探秘:从 .exsd 扩展点到锁定视图布局
MITK/BlueBerry 插件机制探秘:从 .exsd 扩展点到锁定视图布局本文基于 MITK 源码(BlueBerry 框架)整理,梳理三个相关联的问题:.exsd文件是什么、什么时候用?一个plugin.xml为什么会同时出现多个extension?MITK 的视图拖动功能能不能关闭?已发布的程序怎么办?一、.exsd 文件:扩展点的 Schema 定义MITK 的界面框架 BlueBerry 移植了 Eclipse 的插件/扩展点(Extension Point)机制。.exsd是Extension Point Schema Definition的缩写,即扩展点的 Schema 定义文件,用于描述某个扩展点接受什么样的 XML 结构。什么时候需要写 .exsd?只有当你要定义一个新的扩展点时才需要。做法是在plugin.xml中用extension-point声明扩展点,并用schema属性指向.exsd文件:extension-pointidorg.mitk.example.extensionpointdefinition.changetextnameChange Text of Labelschemaschema/changetext.exsd/MITK 源码中有一个完整的官方示例:Examples/Plugins/org.mitk.example.gui.extensionpointdefinition。.exsd的内容本质上是一段 XML Schema,规定了扩展方在自己的plugin.xml里写extension point...时,可以/必须提供哪些元素和属性。例如changetext.exsd中定义了changetext元素必须带id、name、class三个属性:elementnamechangetextcomplexTypeattributenameidtypestringuserequired/attributenamenametypestringuserequired/attributenameclasstypestringuserequired//complexType/elementBlueBerry 内置的扩展点也都是这么定义的。org.blueberry.ui.qt插件的plugin.xml中声明了十几个扩展点,每个都配有.exsd:扩展点Schema 文件用途org.blueberry.ui.viewsviews.exsd注册视图(View)org.blueberry.ui.editorseditors.exsd注册编辑器(Editor)org.blueberry.ui.perspectivesperspectives.exsd注册透视图(Perspective)org.blueberry.ui.preferencePagespreferencePages.exsd注册偏好设置页org.blueberry.ui.keywordskeywords.exsd注册偏好设置搜索关键词一个容易误解的点:.exsd 不参与运行时校验在 MITK/BlueBerry 的 C 运行时中,.exsd文件并不会被用来校验plugin.xml。运行时只是通过ExtensionPoint::GetSchemaReference()记录这个路径字符串而已(见berryExtensionPoint.cpp)。它的实际作用是:文档作用:告诉扩展方该扩展点的 XML 应该怎么写(每个属性的含义、是否必填);工具支持:用 Eclipse PDE 工具编辑plugin.xml时可获得表单编辑与校验;格式兼容:保持与 Eclipse 插件体系一致。结论:如果你只是扩展别人的扩展点(比如注册一个 View),不需要创建 .exsd,只需按照对应 .exsd 描述的格式在自己的 plugin.xml 里写extension即可。二、为什么一个 plugin.xml 里有多个 extension?先澄清概念:extension-point是定义扩展点,extension是扩展(向已有扩展点贡献内容)。两者经常被混为一谈。以 MITK 标准四窗口编辑器插件org.mitk.gui.qt.stdmultiwidgeteditor的plugin.xml为例,它同时扩展了三个扩展点:plugin!-- 1. 注册编辑器本身 --extensionpointorg.blueberry.ui.editorseditoridorg.mitk.editors.stdmultiwidgetnameStandard DisplaydefaulttrueclassQmitkStdMultiWidgetEditor//extension!-- 2. 注册它的偏好设置页 --extensionpointorg.blueberry.ui.preferencePagespageidorg.mitk.StdMultiWidgetEditorPreferencePagenameStandard Multi WidgetclassQmitkStdMultiWidgetEditorPreferencePagecategoryorg.mitk.EditorsPreferencePagekeywordreferenceidorg.mitk.StdMultiWidgetEditorPreferencePageKeywords//page/extension!-- 3. 注册偏好设置页的搜索关键词 --extensionpointorg.blueberry.ui.keywordskeywordidorg.mitk.StdMultiWidgetEditorPreferencePageKeywordslabelcrosshair gap size background decoration color corner annotation//extension/plugin三个extension是层层配套的关系:编辑器 (editors) └── 它的设置页 (preferencePages) └── 设置页的搜索关键词 (keywords)editors:告诉工作台存在一个叫 “Standard Display” 的编辑器,由QmitkStdMultiWidgetEditor实现,且是默认编辑器;preferencePages:这个编辑器有可配置项(十字线间隙、背景色、抗锯齿等),所以向 Preferences 对话框贡献一个设置页,通过category挂到 “Editors” 分类下;keywords:偏好设置对话框有搜索框,这里的关键词通过keywordreference关联到设置页——用户搜 “crosshair” 就能找到它。这就是 Eclipse/BlueBerry 插件体系的典型模式:一个插件 一组相关功能的集合,每类功能通过对应的扩展点声明式注册。框架启动时读取这些声明,按需懒加载实际的 C 类,插件之间无需硬编码依赖。所以同时出现多个 extension不是冗余,而是一个完整功能单元的多个组成部分。三、MITK 的视图拖动功能可以关闭吗?可以。BlueBerry 提供了两个层级的开关,都在定义 Perspective 的CreateInitialLayout()里设置。方式一:锁定整个 Perspective(全局禁止拖动)voidMyPerspective::CreateInitialLayout(berry::IPageLayout::Pointer layout){layout-AddView(org.mitk.views.datamanager,berry::IPageLayout::LEFT,0.3f,layout-GetEditorArea());// ...其他视图...layout-SetFixed(true);// 布局固定:所有视图不可拖动、不可缩放}berryIPageLayout.h中对SetFixed的说明是:“In a fixed layout, layout parts cannot be moved or zoomed”。拖动的判断逻辑在berryPartStack.cpp中:return!perspective-IsFixedLayout();// fixed 时整个 PartStack 都不允许拖拽如果 Perspective 是纯声明式注册的,也可以直接在plugin.xml中给perspective加fixedtrue属性(perspectives.exsd里定义了这个属性)。注意:SetFixed(true)同时会隐藏视图标签上的关闭按钮、禁止缩放,不只是禁用拖动。方式二:只锁定某个视图(细粒度控制)如果只想禁止个别视图被拖动,其他视图保持自由,用IViewLayout:voidMyPerspective::CreateInitialLayout(berry::IPageLayout::Pointer layout){layout-AddView(org.mitk.views.datamanager,berry::IPageLayout::LEFT,0.3f,layout-GetEditorArea());berry::IViewLayout::Pointer viewLayoutlayout-GetViewLayout(org.mitk.views.datamanager);viewLayout-SetMoveable(false);// 该视图不可拖动// viewLayout-SetCloseable(false); // 顺带也可以禁止关闭}一个坑:布局是持久化的这些设置只在 Perspective初次创建布局时生效。如果之前运行过程序,工作台会从上次会话恢复布局(fixed 状态也会被持久化)。测试时建议先Window → Reset Perspective,或清除工作台状态缓存(见下一节)。四、已发布的程序怎么办?上面的SetFixed()/SetMoveable()都是开发期的 C 接口,必须改源码重新编译。对于已经发布(编译好的)的 MITK Workbench:没有用户可见的开关。MITK Workbench 的 Preferences 里没有锁定布局选项。Eclipse 的 “Lock the toolbars” 相关代码在 BlueBerry 移植时是被注释掉的(berryWorkbenchWindow.cpp),而且那也只是锁工具栏。plugin.xml 也改不了。MITK 发布版中每个插件的plugin.xml是作为 Qt 资源编译进插件的 DLL/so 里的,不是磁盘上的独立文件,无法事后修改。唯一不重编译的后门:手改工作台状态文件(仅适合临时验证,见下文)。结论:要给最终用户提供不能拖乱界面的产品,正规做法只有一条——在自己的 Perspective 源码里SetFixed(true)(或对个别视图SetMoveable(false))然后重新构建发布。用户拖乱了布局,只能靠 Window → Reset Perspective 恢复。五、附:BlueBerry 工作台状态文件在哪?工作台布局保存在workbench.xml(berryWorkbench.cpp中的DEFAULT_WORKBENCH_STATE_FILENAME),位于org.blueberry.ui.qt插件的数据目录下。整个 BlueBerry 存储根目录的确定逻辑在berryInternalPlatform.cpp:如果启动时指定了BlueBerry.storage_dir属性(命令行--BlueBerry.storage_dir路径),就用指定目录;否则默认为:QStandardPaths::GenericDataLocation 组织名 / 应用名 _ qHash(程序安装路径) /Windows 上GenericDataLocation是C:\Users\用户名\AppData\Local,所以官方 MITK Workbench 的状态目录大致是:C:\Users\用户名\AppData\Local\DKFZ\MitkWorkbench_一串数字哈希\Linux 上对应~/.local/share/组织名/应用名_哈希/。几个要点:路径末尾带一个安装路径的哈希值——同一程序装在不同目录会各有一份独立状态(源码注释:“allows to start the same application from different build or install trees”);程序启动时日志会打印Framework storage dir: ...,这是最直接的确认方式;目录里bb-metadata\bb-plugins\插件目录\存放各插件数据,workbench.xml在其中org.blueberry.ui.qt对应的子目录下;.BlueBerryPrefs是偏好设置文件;整个目录删掉等于恢复出厂布局;启动参数--BlueBerry.clean也会清掉缓存状态。如果想验证锁定布局的效果而不重编译:关闭程序,在workbench.xml的perspective节点上加fixed1,下次启动会按锁定布局恢复(恢复逻辑见berryPerspective.cpp对TAG_FIXED的读取)。但这个文件格式无文档、程序每次正常退出都会重写,只适合临时验证,不要作为产品方案。总结问题答案.exsd 何时用仅在定义新扩展点时;扩展已有扩展点不需要.exsd 运行时校验吗不校验,主要是文档 Eclipse PDE 工具支持多个 extension 为什么一个插件的多类功能各自注册到对应扩展点,层层配套禁止视图拖动layout-SetFixed(true)或viewLayout-SetMoveable(false),需重编译已发布程序无开关、plugin.xml 编译在二进制里改不了;只能手改 workbench.xml 临时验证状态文件位置%LOCALAPPDATA%\组织\应用_哈希\bb-metadata\bb-plugins\...\workbench.xml本文源码引用基于 MITK 主线(BlueBerry 框架),文中提到的文件路径:Plugins/org.blueberry.ui.qt/、Plugins/org.blueberry.core.runtime/、Examples/Plugins/org.mitk.example.gui.extensionpointdefinition/。

相关新闻

贸易结算用气体涡轮流量计,温压补偿不做误差到底多大?艾丝特ATWG硬件配置与技术原理解读

贸易结算用气体涡轮流量计,温压补偿不做误差到底多大?艾丝特ATWG硬件配置与技术原理解读

一、引言在天然气贸易结算和工业气体计量中,气体涡轮流量计因其压力损失小、精度高、量程比宽而成为应用最广泛的仪表类型之一。然而,采购人员在实际选型时常面临一个核心矛盾:进口品牌精度高但价格高、备件周期长;国产品牌价格低…

2026/10/19 7:43:27 阅读更多 →
Typhoon OCR 1.5 2B 8位模型路线图:未来功能更新与性能优化展望

Typhoon OCR 1.5 2B 8位模型路线图:未来功能更新与性能优化展望

Typhoon OCR 1.5 2B 8位模型路线图:未来功能更新与性能优化展望 【免费下载链接】typhoon-ocr1.5-2b-8bit 项目地址: https://ai.gitcode.com/hf_mirrors/mlx-community/typhoon-ocr1.5-2b-8bit Typhoon OCR 1.5 2B 8位模型是基于Qwen3-VL的视觉语言模型&am…

2026/10/18 11:12:19 阅读更多 →
RevitLookup终极指南:5分钟掌握BIM数据透视神器,轻松解决Revit开发调试难题

RevitLookup终极指南:5分钟掌握BIM数据透视神器,轻松解决Revit开发调试难题

RevitLookup终极指南:5分钟掌握BIM数据透视神器,轻松解决Revit开发调试难题 【免费下载链接】RevitLookup Interactive Revit RFA and RVT project database exploration tool to view and navigate BIM element parameters, properties and relationshi…

2026/10/20 9:21:23 阅读更多 →

最新新闻

Deepagents自动化测试实战:从断言设计到稳定性体系建设

Deepagents自动化测试实战:从断言设计到稳定性体系建设

做过AI Agent相关开发的朋友应该都有同感:写一个能跑通的代理不难,难的是让它稳定地跑完一百遍。LLM天然带有随机性,同样的输入,今天输出这个结果,明天就可能换个路径,哪怕最终答案都对,中间调用…

2026/10/20 23:44:36 阅读更多 →
AirMICROSD_1000直插式存储模块:嵌入式设备灵活扩容与量产可靠性实践

AirMICROSD_1000直插式存储模块:嵌入式设备灵活扩容与量产可靠性实践

去年秋天我在做一台边缘采集设备的量产改版,原方案用的是板载eMMC,结果代工厂那边封装炉温曲线一直调不理想,整板不良率居高不下。换方案的时候,朋友递过来一块AirMICROSD_1000直插式存储扩展模块,说你先试试这个。刚开…

2026/10/20 23:44:36 阅读更多 →
电热联合调度微电网运行优化模型:MATLAB+YALMIP实现解析

电热联合调度微电网运行优化模型:MATLAB+YALMIP实现解析

做微电网运行优化,绕不开一个朴素的问题:电负荷和热负荷明明共存于同一个园区,为什么大多数优化模型只盯着“电”在算?我最近在某园区微电网项目的经济调度分析里,把基于电热联合调度的微电网运行优化模型在 MATLAB 里…

2026/10/20 23:44:36 阅读更多 →
Java实现Word与PDF全文检索:Elasticsearch 7.x文档解析、IK分词与高亮查询实战

Java实现Word与PDF全文检索:Elasticsearch 7.x文档解析、IK分词与高亮查询实战

1. 从一份合同翻找说起:为什么Word和PDF的全文检索值得单独做前阵子帮一个做企业文档管理的朋友处理一个需求,他们内部有几千份Word合同和PDF技术方案,平时找一份文件只能靠文件名,可文件名往往起得极其随意,比如“最终…

2026/10/20 23:44:36 阅读更多 →
逆向工程Agent实战:从架构设计到落地优化的完整指南

逆向工程Agent实战:从架构设计到落地优化的完整指南

1. 逆向工程 Agent 到底在做什么1.1 从一个真实需求说起去年下半年开始,我陆续接触到几个做安全研究的朋友,他们不约而同地提到同一件事:手头需要分析的二进制样本越来越多,但人手根本没变。以前一个熟练的逆向工程师一天能啃完一…

2026/10/20 23:44:36 阅读更多 →
VS Code Jupyter内核崩溃排查:Kernel died with exit code 1全链路解析

VS Code Jupyter内核崩溃排查:Kernel died with exit code 1全链路解析

1. 从一个让人抓狂的报错说起如果你在 VS Code 里用 Jupyter 跑过代码,大概率见过这个弹窗:"Kernel died with exit code 1"。它不像语法错误那样给你一行红色波浪线,也不像缺包那样告诉你ModuleNotFoundError,它就是一…

2026/10/20 23:43:35 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 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/20 10:02:08 阅读更多 →
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/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练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/20 9:50:45 阅读更多 →