基于Qt6 + MuPDF在 Arm IMX6ULL运行的PDF浏览器——MuPDF Adapter文档
-
项目地址:总项目Charliechen114514/CCIMXDesktop: This is a Qt Written Desktop with base GUI Utilities
-
本子项目地址:CCIMXDesktop/extern_app/pdfReader at main · Charliechen114514/CCIMXDesktop
前言
这个部分说的是Mupdf_adaper下的文档的工作函数的接口含义,如果你想要进行进一步的修改和优化,请自己修改源码和优化实现,或者如果你在使用中有任何问题,可以提交到Github Issue上询问我,或者是在CSDN博客下私信我等都可以,或者直接在CSDN平台上有条有理的提问,好让我帮助你。
类名:CCPdfDocument
CCPdfDocument
是一个用于管理和访问 PDF 文档的 C++ 类,它基于 MuPDF 库进行封装,并通过 QObject
实现与 Qt 信号系统的结合。该类封装了文档的打开、关闭、页码跳转、元信息查询等常用操作,目的是为上层应用提供一个清晰、可靠的 PDF 操作接口。
一、设计目标
该类面向的是需要“持有文档资源”的场景,也就是说,它内部维护了 PDF 的底层句柄(MuPDF 的 fz_document
与 fz_context
),并且会负责整个文档生命周期的管理。由于它是一个“重量级”的类,所以不适合频繁创建和销毁,应尽可能复用一个对象处理多个操作。
为了增强稳定性,该类设计时不直接暴露底层资源,而是提供相对安全的接口,并封装了部分异常处理逻辑(如通过返回错误码来替代异常抛出,笔者认为嵌入式场景如果出现频繁的异常抛出是不合适的)。此外,通过 Qt 的信号机制,它还能将文档加载状态等事件及时通知 UI 或上层逻辑。
二、构造与析构
类提供了两个构造函数。一个是默认构造函数,另一个接收一个文档路径参数并自动加载文档。析构函数会自动关闭文档并释放资源,用户不必手动处理底层句柄的释放。
三、文档操作方法说明
load_document
是用于加载 PDF 文件的主要接口,它返回一个错误码,表示成功或失败的类型,如文件不存在或其他错误。 close_document
则用于关闭已打开的文档并释放资源。 document_loaded
用于判断当前是否有有效文档处于加载状态。 document_page
提供当前文档的总页数,它使用了 std::optional
类型,表示如果文档未加载,返回空值。 此外,类还提供了底层句柄的访问函数:raw_handle
和 raw_context
,但建议仅限于高级用户使用。
四、页码跳转支持
该类支持通过 jump
函数跳转到指定页码。它会检查页码合法性,如果越界或文档未加载,会返回合适的错误码(如溢出、下溢、页面不存在等),便于上层逻辑进行提示或纠正。当前页码和总页数可通过 current_page
与 total_pages
获取。
五、元信息支持
类内部还封装了一个 CCPdfMetaInfo
类型的元信息对象,通过 meta_info
函数获取。
六、信号机制
类定义了两个 Qt 信号:
-
document_load
:在文档成功加载后发出,携带文档路径信息; -
pageIndexChanged
:当页码发生变化(例如跳转)时发出,便于 UI 层响应更新。
七、错误处理机制
类中定义了两个枚举类型用于错误处理:
-
ErrorCode
表示文档加载时的错误状态; -
PageNavigationError
表示跳转页码时可能出现的错误。
这种设计方式有助于在不使用异常的情况下,仍然提供清晰的错误反馈路径。
八、私有成员说明
privated
是一个内部的私有实现指针(PIMPL 模式),用于封装实际的数据结构或 MuPDF 接口细节。这样做可以隐藏实现细节,避免头文件过度暴露依赖。 holding_path
保存当前打开的 PDF 路径,current_page_index
表示当前页码,total_page
表示总页数,这些变量用于记录状态。
类名:CCPdfChapterCreator
CCPdfChapterCreator
是一个用于提取和展示 PDF 文档目录结构(通常也叫做“章节”或“书签”)的辅助类。它的作用是从一个已打开的 PDF 文档中读取章节信息,并将其以树状形式呈现到指定的 Qt 控件中,便于用户浏览。
一、设计目的
该类的主要用途是服务于用户界面的章节展示功能。很多 PDF 文档带有内嵌目录结构,比如图书或论文中常见的“目录”部分,这些信息在 PDF 内部以 Outline 或 Bookmarks 的形式存在。通过 MuPDF 库的功能,可以读取这类信息,并在程序中以图形化方式展示。CCPdfChapterCreator
就是承担这个职责的类。
二、构造函数说明
构造函数非常简洁,它自动将 parse_start
信号连接到内部的 process_parse
槽函数。这种设计允许外部仅通过发出信号即可启动目录的解析逻辑,保持了代码结构的松耦合。
三、绑定界面组件
该类通过 bindSolvedTreeWidget
函数将某个 QTreeWidget
控件绑定进来。这个控件就是章节目录要展示的位置。在解析完成后,章节信息将被插入到该控件中,呈现出层级结构,类似于电子书中的目录。
四、文档解析与设置
parse_and_set
是外部调用的主要接口,传入一个已经加载的 CCPdfDocument
文档指针,表示希望对这个文档的章节结构进行分析。调用该函数后,内部会发出 parse_start
信号,进而触发解析流程。
五、解析流程与信号机制
内部使用 process_parse
进行实际解析逻辑,该函数作为私有成员,避免外部误调用。解析完成后会发出 parse_finish
信号,返回一个章节节点列表(QList<CCPdfChapterNode>
)。这些章节节点应该包含了章节名称、起始页码、层级关系等信息,供 UI 控件使用。
通过 parse_start
与 parse_finish
这两个信号,可以将解析过程拆分为“请求-完成”两个步骤,也方便后续扩展,例如添加加载动画或异步处理。
六、内部状态管理
该类内部仅维护了一个指向 QTreeWidget
的指针,名为 widget_handling
,用于记录当前展示目录的控件对象。其生命周期应由外部维护,CCPdfChapterCreator
不拥有该控件的所有权。
以下是对 CCPdfViewer
类头文件所对应的工程文档说明,延续之前的风格,力求以平实语言解释类的功能与用途,方便理解和维护。
类名:CCPdfViewer
CCPdfViewer
是一个基于 Qt 的 PDF 页面显示控件,它继承自 QWidget
,可以嵌入到任何 Qt 应用中,实现对 PDF 单页图像的显示。它负责将 PDF 页面渲染成图像,并将其展示在界面上,同时支持基本的缩放交互。
一、设计目的
该类的目的是提供一个面向页面级别的 PDF 浏览控件。它不关注整个文档的章节或多页内容,只处理当前页面的图像展示。由于 MuPDF 库本身不直接提供图像显示功能,本类结合内部工具(如 page_renderer
)将页面渲染为 QImage
图像,再通过 QLabel
控件显示在界面上。
二、文档绑定机制
类通过 bindDocument
函数接收一个已经打开的 CCPdfDocument
对象。如果绑定失败(如文档未加载或无效),函数会返回 false
。 调用 unbindDocument
可以解除绑定,清除显示内容,常用于关闭文档或更换文档。
三、缩放功能
控件支持页面缩放,通过 view_zoom
变量记录当前缩放比例,初始为 1.0(即 100% 大小)。 可以通过 set_zoom_step
设置每次缩放的步长,默认是 0.1。 类中定义了一个 ZoomDirection
枚举,表示缩放的方向,分为放大(ZOOM_IN)与缩小(ZOOM_OUT)。 调用 zoom
函数可以改变缩放值,而 fresh_zoom
则会在改变缩放后自动触发重绘操作。通过这种方式,用户可以自由控制文档视图的大小。
四、页面渲染与更新
fresh_render
是核心的渲染函数。它会从当前绑定的 PDF 文档中读取当前页内容,并渲染为图像(QImage
),再通过内部 QLabel
展示在滚动区域中。如果缩放比例发生变化,重新调用此函数也能更新显示内容。
五、内部成员与 UI 结构
控件内部使用了 QLabel* imageLabel
作为主要图像展示区域,该标签通常嵌入在 QScrollArea
中,从而支持图像超出视窗时的滚动浏览。 变量 cached_image
用于缓存渲染出的图像,避免重复生成。 init_internal
是一个私有函数,负责初始化控件内部结构,比如创建标签、设置布局等。 此外,类使用了 Qt Designer 自动生成的 UI 类指针 Ui::CCPdfViewer *ui
,说明本控件的界面结构可能通过 .ui
文件部分定义,便于可视化编辑。
六、信号与槽机制
目前该类未定义新的信号,主要通过槽函数处理交互行为,包括缩放与渲染。由于缩放操作非常常见,因此 zoom
与 fresh_zoom
被设计为 inline
函数以提高效