ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

零基础开发 Xournal++ Lua 插件:3 个实战示例带你实现笔记自动化

零基础开发 Xournal++ Lua 插件:3 个实战示例带你实现笔记自动化 零基础开发 Xournal Lua 插件3 个实战示例带你实现笔记自动化【免费下载链接】xournalppXournal is a handwriting notetaking software with PDF annotation support. Written in C with GTK3, supporting Linux (e.g. Ubuntu, Debian, Arch, SUSE), macOS and Windows 10. Supports pen input from devices such as Wacom Tablets.项目地址: https://gitcode.com/gh_mirrors/xo/xournalppXournal 是一款基于 C 与 GTK3 的开源手写笔记软件支持 PDF 标注、压感笔输入横跨 Linux、macOS 与 Windows 三大平台。本文面向想扩展笔记工作流的开发者通过 3 个可直接运行的示例带你从认识插件目录结构开始逐步掌握app.registerUi、app.changeActionState等核心 API最终把一键切换网格纸循环换色这类操作变成你自己的脚本真正让手写笔记告别重复劳动。为什么要给手写笔记软件写插件用 Xournal 记笔记久了你会发现一个规律反复在做的事就那么几件。上课前要把页面切成网格纸、写重点时想快速换一支红色笔、演示时要隐藏工具栏。这些操作虽然都藏在菜单里但每做一次就要点两三下一天下来浪费的时间不少。Xournal 的插件系统正是为解决这类高频重复操作而生的。它不要求你懂 C也不要求重新编译整个项目——插件就是一个普通的目录里面放一个plugin.ini配置文件和若干个 Lua 脚本。软件启动时会把所有插件目录扫描出来你可以在插件管理器中一键启用之后就能在菜单栏直接点到自己写的功能按钮。先认识一个插件的身份证plugin.ini每个插件目录的入口是plugin.ini它负责告诉 Xournal 三件事这个插件是谁写的、默认是否启用、主脚本叫什么。以项目自带的示例插件为例见plugins/Example/plugin.ini[about] authorAndreas Butti descriptionThis is a minimal example plugin, for reference versionxournalpp [default] enabledfalse [plugin] mainfilemain.lua拆开看三个小节[about]作者、描述、版本号。versionxournalpp表示跟随软件版本你也可以写死如1.0。[default]enabledfalse表示插件安装后默认关闭需要你在插件管理器里手动打开。[plugin]mainfilemain.lua指定主脚本文件名Xournal 启动时会加载它。插件放在哪里有两条搜索路径软件安装目录下的../plugins以及你的配置目录中的plugins子目录个人目录优先级更高适合放自己写的插件。插件管理器界面菜单插件 管理插件就是扫描这两个目录得到的列表其扫描与启用逻辑可以在src/core/plugin/PluginController.cpp中看到。插件的心脏initUi 与注册回调配置好plugin.ini之后真正干活的是 Lua 脚本。Xournal 用一个全局对象app向脚本暴露全部功能而脚本里最先被执行的是一个约定函数initUi()。程序在初始化阶段会检查这个函数是否存在并调用它对应源码src/core/plugin/Plugin.cpp中的registerToolbar逻辑你的 UI 注册代码必须放在这里面。来看最简写法复制plugins/Example/main.lua-- 初始化注册菜单项 function initUi() app.registerUi({ [menu] Test123, [callback] exampleCallback, [accelerator] Controlt }) end -- 点击菜单后触发 function exampleCallback() app.openDialog(Test123, {Yes, No}, dialogCallback) end -- 用户点击对话框按钮后触发 function dialogCallback(result) print(result .. result) end关键点有三个app.registerUi只能在initUi里调用它把菜单项挂到插件菜单下。menu是显示名称callback是点击后要执行的函数名accelerator可选用来绑定快捷键。回调函数名要与注册字符串完全一致Xournal 通过名字在脚本里查找并调用它们。app.openDialog的第三个参数是回调函数名按钮编号会作为参数传给它。实战一给当前页面一键切换网格纸最典型的需求是换页面背景。项目自带的plugins/ToggleGrid/togglegrid.lua给出了教科书级的实现——用一个布尔变量记录当前状态来回切换网格纸与空白纸function initUi() app.registerUi({[menu] Toggle Grid Paper, [callback] toggleGridPaper}) end local toggleState false function toggleGridPaper() if toggleState true then app.changeActionState(grid-snapping, true) app.changeCurrentPageBackground(graph) else app.changeActionState(grid-snapping, false) app.changeCurrentPageBackground(plain) end toggleState not toggleState end这段代码引入两个高频 APIapp.changeActionState(action, state)修改界面动作的状态这里把网格吸附开关也一并联动保证画线时自动对齐网格。动作名如grid-snapping、zoom、tool-color完整清单见plugins/luapi_application.def.lua中的 Action 列表。app.changeCurrentPageBackground(graph)把当前页背景切换为网格纸其他取值还有plain空白、lined横线、ruled方格等。避坑提示涉及枚举类型的动作如工具类型、笔迹粗细不要硬编码数字要使用app.C常量表例如app.C.Tool_pen这样能兼容未来版本变化。实战二3 步实现循环换色笔第二个场景来自plugins/ColorCycle/main.lua演示课想连续换红、蓝、绿几支笔的颜色手动点色板太慢不如写个循环切换。它的思路是准备一张颜色表 → 维护一个当前索引 → 每次触发把索引往后挪一位 → 通过app.changeToolColor应用到当前工具function initUi() app.registerUi({[menu] Cycle through color list, [callback] cycle, [accelerator] Altc}) end local colorList { {black, 0x000000}, {red, 0xff0000}, {blue, 0x3333cc}, {green, 0x008000}, {yellow, 0xffff00} } local currentColor 0 function cycle() currentColor currentColor % #colorList 1 -- 应用到当前工具并同步改选中元素的颜色 app.changeToolColor({[color] colorList[currentColor][2], [selection] true}) end与changeActionState不同app.changeToolColor接收的是参数表而非两个位置参数。表里color是 0xRRGGBB 格式的颜色值selectiontrue表示同时把当前选区里的元素也染成新颜色如果只想改笔的颜色则传[tool] pen即可。这个示例还展示了插件的状态保持特性脚本里的局部变量currentColor在两次调用之间是保留下来的所以你可以用 Lua 变量记录插件的运行状态而无需写配置文件。进阶玩法不止于点菜单的自动化上面两个示例都是手动触发但插件 API 的能力远不止此。细读plugins/luapi_application.def.lua这是官方 API 参考文档每个函数都有完整签名与示例你会发现整套文档操作都对你开放批量写入内容app.addStrokes按坐标数组批量画笔画app.addTexts在指定坐标插入文本框app.addImages把本地图片贴进页面均支持allowUndoRedoAction参数individual/grouped/none控制撤销粒度。读取文档结构app.getStrokes(all)返回全文档所有笔迹的坐标、宽度、颜色app.getDocumentStructure()返回每一页的尺寸、图层与背景信息。导出与打开app.export支持把当前文档导出为 PDF、SVG 或 PNGapp.openFile可以代开本地文件并滚动到指定页。工具栏自定义app.registerUi还能注册工具栏图标传toolbarId在工具栏自定义对话框里把Plugin::你的ID拖到工具栏上就能得到一个专属按钮。这些能力组合起来可以做出很实用的工具比如写一个对选中笔迹统一重新着色的批处理、一个一键把当前页导出为图片的快捷导出甚至一个在每页固定位置插入日期文本框的批注工具。参考plugins/目录下其他自带插件Export、FitToContent、LayerActions等的写法能更快上手。开发调试避坑清单把容易踩的坑集中列出来帮你少走弯路改了脚本必须重启生效initUi只在启动时执行一次没有热重载机制。改完代码重启软件才能看到变化。注意回调函数的命名约定registerUi传的callback、openDialog传的第三个参数都是函数名字符串函数必须定义在全局作用域不能定义在local里。插件没出现在菜单里先查两个位置一是插件管理器里是否已启用[default] enabledtrue或手动勾选二是plugin.ini的[plugin]段mainfile文件名是否与脚本文件名完全一致。调试输出用print脚本里的print会打到程序日志中运行软件时用命令行启动如xournalpp直接运行即可看到输出这是最直接的排查手段。枚举值一律走app.C常量不要手写魔法数字去匹配工具类型或线宽档位版本升级后数字可能变化。文件路径用app.getFolder需要读写配置或缓存文件时用app.getFolder(config)/(state)获取专属目录它会自动创建避免污染用户目录。动手练一练把它变成你的第一个插件从头梳理一遍完整流程照着做你就能拥有自己的插件创建目录plugins/下手放一个文件夹比如my-first-plugin/。写入plugin.iniabout段填作者信息plugin段mainfilemain.lua。编写main.lua定义initUi并调用app.registerUi再实现对应的回调函数。启动 Xournal打开插件管理器启用它回到菜单插件下找到你的菜单项试试。Xournal 的插件体系把文档读取、笔迹绘制、UI 注册、文件导出全部封装成了几十个 Lua 函数学习门槛远比想象中低——你今天就能写出第一个一键切换网格纸下一步完全可以挑战批量导出所有页为图片这类自动化脚本。把重复劳动交给脚本把时间留给真正的笔记内容。【免费下载链接】xournalppXournal is a handwriting notetaking software with PDF annotation support. Written in C with GTK3, supporting Linux (e.g. Ubuntu, Debian, Arch, SUSE), macOS and Windows 10. Supports pen input from devices such as Wacom Tablets.项目地址: https://gitcode.com/gh_mirrors/xo/xournalpp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表