news 2026/9/4 23:07:40

KOReader 插件开发上手:5 分钟写出第一个可用菜单项

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
KOReader 插件开发上手:5 分钟写出第一个可用菜单项

KOReader 插件开发上手:5 分钟写出第一个可用菜单项

【免费下载链接】koreaderAn ebook reader application supporting PDF, DjVu, EPUB, FB2 and many more formats, running on Cervantes, Kindle, Kobo, PocketBook and Android devices项目地址: https://gitcode.com/GitHub_Trending/ko/koreader

想加个自动翻页,文档却只给一行签名

想给电子阅读器加个定时自动翻页,翻遍 KOReader 的文档,只找到一行 API 签名——插件到底怎么被加载?菜单项怎么进到系统菜单里?_meta.luamain.lua各管什么?读完这篇,你能独立写出第一个可用的 KOReader 插件,并避开目录命名、菜单注册、设置持久化这 3 个最常见的坑。

跑通最小插件:两个文件就够

先拉一份源码用来对照着看;插件本体要放进你自己设备上的 KOReader 安装目录,这份源码只读参考,不动它:

  1. git clone https://gitcode.com/GitHub_Trending/ko/koreader
  2. 在设备端 KOReader 目录下创建plugins/mytool.koplugin/目录,名字必须以.koplugin结尾,加载器按这个规则匹配,写成别的不会加载
  3. 目录里放一个_meta.lua,只声明fullnamedescription两行;再放下面这个main.lua
  4. 重启 KOReader,打开系统菜单
local UIManager = require("ui/uimanager") local InfoMessage = require("ui/widget/infomessage") local WidgetContainer = require("ui/widget/container/widgetcontainer") local MyTool = WidgetContainer:extend{name = "mytool", is_doc_only = false} function MyTool:init() self.ui.menu:registerToMainMenu(self) end function MyTool:addToMainMenu(menu_items) menu_items.my_tool = { text = "MyTool", sorting_hint = "more_tools", callback = function() UIManager:show(InfoMessage:new{text = "Hello, KOReader"}) end, } end return MyTool

预期现象:系统菜单的"更多工具"区块里多出一个 MyTool 条目,点一下,屏幕顶部短暂弹出 Hello, KOReader 文字。

菜单注册背后发生了什么

如果你只记住一件事,就是:插件本身没有任何 UI 入口,你在菜单里看到的那一项,是你"注入"给宿主菜单系统的一张表。

启动时 pluginloader 扫描plugins/目录,名字符合.koplugin后缀的目录都算插件,main.lua必须能 require 并返回一个类,这个类要继承 WidgetContainer——让插件能收到生命周期回调的 UI 容器基类。加载完成后宿主会调用插件的init(),你在里面执行self.ui.menu:registerToMainMenu(self),等于声明"我要占一个菜单位"。

真正的组装在后面:菜单系统会回调你的addToMainMenu(menu_items),你把一张表塞进menu_itemstextsorting_hintcallback三个字段分别决定文案、位置和点击后的动作。说白了,是宿主的菜单"借用"了你的回调,不是插件自己弹出一个窗口。

这里有 3 个坑。第一个最隐蔽:init里漏了registerToMainMenuaddToMainMenu就永远不会被调用,菜单凭空消失。第二个:sorting_hint不写,条目会被甩到菜单末尾,写more_toolsnavi才能进对应区块。第三个:官方 hello 示例插件 默认处于禁用状态,照着抄要先去掉禁用标记,菜单不出现不是报错。

两个高频场景:记住设置、响应触摸

场景 A:让设置跨重启存活

最高频的日常需求:这次调好的值,下次打开还在。KOReader 向宿主注入了一个全局设置对象G_reader_settings,键值对写在设备端配置文件里,插件只需要读写,不用自己建文件:

-- init() 时读:没配置过就取默认值 30 self.seconds = G_reader_settings:readSetting("mytool_seconds", 30) -- 用户通过 SpinWidget 等组件修改后 G_reader_settings:saveSetting("mytool_seconds", self.seconds)

两个坑要注意。G_reader_settings是宿主注入的全局变量,自己写 require 会直接报错;键名要带插件名前缀,否则可能和别的插件撞键,现象很迷惑——你的值看起来被改了,其实是另一个插件在读写。忘 save 也常见:值只留在内存里,重启后回默认,当时还以为是读错了。整段就两行调用,却是一切"记住"功能的地基。

设置存下来了,可时间到了谁去触发翻页?

场景 B:到点自动翻页

需求:每隔 N 秒自动翻一页,用户一碰屏幕就立刻停。思路别用轮询定时器,监听输入事件、随时撤销排程更干净:

function MyTool:init() -- 监听阅读界面的触摸事件 UIManager.event_hook:registerWidget("InputEvent", self) end function MyTool:onInputEvent() self:unschedule() -- 用户一碰屏幕,取消自动翻页 end

触摸事件就从上图这些区域产生,这也是为什么取消排程要挂在InputEvent上。注意两点:事件处理函数按on+ 事件名命名,InputEvent对应onInputEvent,写成onInput()永远不会被调用;要翻页就用self.ui:handleEvent(Event:new("GotoViewRel", 1))通知阅读 UI,别直接调阅读器内部函数。仓库里 autoturn 自动翻页插件 就是这个写法,读一遍可以照着抄。

下一步往哪走

想折腾弹窗、输入框这类界面组件,看 ui/widget/;想摸清完整事件链路,看 dispatcher 源码 和 事件定义;想照抄一个完整实战插件,看 autoturn 源码 和 官方开发指南。

菜单项跑出来只是过了门槛,后面能玩出什么花样,就看你的了。

【免费下载链接】koreaderAn ebook reader application supporting PDF, DjVu, EPUB, FB2 and many more formats, running on Cervantes, Kindle, Kobo, PocketBook and Android devices项目地址: https://gitcode.com/GitHub_Trending/ko/koreader

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/4 23:00:31

51单片机智能电饭锅Proteus仿真与硬件闭环设计

简介:本资源是一套面向嵌入式初学者与单片机课程设计者的完整实践案例,聚焦51单片机在智能家电控制系统中的典型应用——智能电饭锅的原理实现与仿真验证。资源涵盖Proteus电路仿真模型、Keil C语言源程序(含5个.c核心模块与4个.h头文件&…

作者头像 李华
网站建设 2026/9/4 22:59:07

macOS菜单栏实时显示Claude订阅用量:额度窗口与重置时间一眼可见

今天这个项目来自 Hacker News 的 Show HN,定位非常小、非常准:在 macOS 菜单栏常驻显示 Claude 订阅使用量。一句话版本就是,你订阅了 Claude 之后,不用再反复打开网页去看这个 5 小时窗口还剩多少额度、什么时候重置&#xff0c…

作者头像 李华
网站建设 2026/9/4 22:56:53

英伟达35亿投资联发科:CPU与GPU融合如何重塑AI算力版图?

如果只看“英伟达向联发科投资 35 亿美元”这一行标题,很容易把这件事理解成一次半导体行业的大额定增,或者某家芯片公司财务投资朋友圈。但把这次合作拆开看,真正的信息量不在金额本身,而在两个公司要在 AI 基础设施、PC 芯片、汽…

作者头像 李华
网站建设 2026/9/4 22:56:13

拒绝黑盒崇拜:探究 Linux 内核网络栈与 AI 辅助分析的结合

拒绝黑盒崇拜:探究 Linux 内核网络栈与 AI 辅助分析的结合随着大模型和 AI 编程助手的普及,技术社区中出现了一种危险的“黑盒崇拜”思潮:部分开发者认为底层原理(如 Linux 操作系统内核、TCP/IP 协议栈、内存分页机制&#xff09…

作者头像 李华
网站建设 2026/9/4 22:55:41

基于51单片机与Proteus的三极管β值测量系统设计与仿真

简介:本资源是一套面向电子类专业学生、单片机初学者及课程设计实践者的完整仿真教学方案,聚焦三极管电流放大倍数β的数字化测量原理与实现。系统基于51单片机,结合Proteus仿真平台,支持NPN/PNP型三极管在0~500范围内…

作者头像 李华
网站建设 2026/9/4 22:54:45

MARC v1:面向临床场景的多智能体协作框架实践指南

MARC v1 是字节跳动开源的一个面向临床场景的多智能体协作框架。多数医疗 AI 开源项目只做单模型推理,输入一段主诉,直接输出判断,中间过程不可控。MARC 的思路不太一样:它把诊断推理拆成感知、计划、反思、知识、验证五个环节&am…

作者头像 李华