使用Qt + mupdf 实现PDF阅读器,支持翻页(上一页、下一页)

思路:

PDF阅读器:使用mupdf,将PDF文件拆分成单个page页,将page页转为QImage图像,使用QListWidget来装载所有的QImage,这样Qt就可以显示出所有图像(完整的PDF)。

翻页:根据滚动条,确认当前是哪一页,然后实现【上一页、下一页】功能

代码:

// pro文件设置
INCLUDEPATH += mupdf
LIBS += -L$$PWD/lib -llibextract -llibmupdf -llibmuthreads -llibthirdparty QMAKE_CFLAGS_DEBUG += -MTd
QMAKE_CXXFLAGS_DEBUG += -MTd
// 显示PDF文件--PDF阅读器
#include <QListWidget>
#include <QListWidgetItem>
#include <QImage>
#include <QIcon>
#include <QSize>
#include "pdf.h"
#include "fitz.h" // 对控件 QListWidget 属性进行设置
/**
* 1. 使用Qt Create编写的demo,所以 QListWidget 控件是直接在ui文件拉进入的
* 2. 需要对每个 QListWidgetItem 加10px的间隔,不然翻页计算不准,或者是 px_num+1 也行
*/
ui->listWidget->setViewMode(QListView::IconMode);
ui->listWidget->setIconSize(QSize(1050, 1485));
ui->listWidget->setSpacing(10);
ui->listWidget->setResizeMode(QListView::Adjust);
ui->listWidget->setMovement(QListView::Static); // 显示 PDF
fz_context* ctx = fz_new_context(NULL, NULL, FZ_STORE_DEFAULT);
fz_register_document_handlers(ctx); // *:这里报错,就需要设置 MTD 或者 MDD
fz_document* doc = fz_open_document(ctx, "F:\\1.pdf"); int pageCount = fz_count_pages(ctx, doc); float zoom = (float)300 / (float)72;
fz_matrix ctm = fz_scale(zoom, zoom); for(int i=0; i<pageCount; i++)
{
fz_pixmap* pix = fz_new_pixmap_from_page_number(ctx, doc, i, ctm, fz_device_rgb(ctx), 0); float b = (float)pix->w / (float)1050;
int t_h = pix->h / b;
QSize t_size(1050, t_h); QImage img(pix->samples, pix->w, pix->h, pix->stride, QImage::Format_RGB888);
img = img.scaled(1050, t_h); QListWidgetItem *tempImageItem = new QListWidgetItem;
tempImageItem->setIcon(QIcon(QPixmap::fromImage(img)));
tempImageItem->setSizeHint(t_size);
ui->listWidget->addItem(tempImageItem); fz_drop_pixmap(ctx, pix);
} fz_drop_document(ctx, doc);
fz_drop_context(ctx);
// 获取当前是哪一页
int getShowPageIndex()
{
// image_height 是 1485,在最开始设置 QListWidget 时就有用到
int px_num = ui->listWidget->verticalScrollBar()->value();
double page_num = ceil(px_num / image_height);
return page_num;
} // 上一页
int page_num = getShowPageIndex();
if(page_num > 0)
ui->listWidget->setCurrentRow(page_num-1, QItemSelectionModel::Current); // 下一页
int page_num = getShowPageIndex();
int page_count = ui->listWidget->count(); if(page_num < page_count-1)
ui->listWidget->setCurrentRow(page_num+1, QItemSelectionModel::Current);

代码比较简单,但是研究mupdf这个库还是花了点时间的,实属不易

另:公司使用的时候,可能还需要讲签名图片贴到PDF上,请参考另一篇文章:mupdf实用操作

Qt + mupdf 显示PDF,支持翻页的更多相关文章

  1. html 打印代码,支持翻页

    ylbtech_html_print html打印代码,支持翻页 <html> <head> <meta name=vs_targetSchema content=&qu ...

  2. flex布局构建大屏框架并支持翻页动画、滚动表格功能

      本文将利用flex属性构建大屏可视化界面.界面主要分标题栏.工具栏.数据可视化窗口.其中,翻页动画以及滚动表格功能分别分布在数据可视化界面两侧. 鼠标点击标题,可看到左侧窗口翻转动画: 整体布局效 ...

  3. iOS:UIPageViewController翻页控制器控件详细介绍

    翻页控制器控件:UIPageViewController 介绍: 1.它是为我们提供了一种类似翻书效果的一种控件.我们可以通过使用UIPageViewController控件,来完成类似图书一样的翻页 ...

  4. PHP.25-TP框架商城应用实例-后台2-商品列表页-搜索、翻页、排序

    商品列表页 1.翻页 控制器GoodsController.class.php添加方法lst(),显示列表页 在商品模型GoodsModel.class.php类中添加search方法 /** *实现 ...

  5. 转:在 C# 中使用 P/Invoke 调用 Mupdf 函数库显示 PDF 文档

    在 C# 中使用 P/Invoke 调用 Mupdf 函数库显示 PDF 文档 一直以来,我都想为 PDF 补丁丁添加一个 PDF 渲染引擎.可是,目前并没有可以在 .NET 框架上运行的免费 PDF ...

  6. Qt仿Android带特效的数字时钟源码分析(滑动,翻页,旋转效果)

    这个数字时钟的源码可以在Qt Demo中找到,风格是仿Android的,不过该Demo中含有三种动画效果(鉴于本人未曾用过Android的系统,因此不知道Android的数字时钟是否也含有这三种效果) ...

  7. 自己定义 ViewGroup 支持无限循环翻页之三(响应回调事件)

    大家假设喜欢我的博客,请关注一下我的微博,请点击这里(http://weibo.com/kifile),谢谢 转载请标明出处,再次感谢 ################################ ...

  8. OpenOffice将MS docx转换成pdf文件偶数页眉不显示问题解决办法

    OpenOffice版本:4.0(Windows.Linux下测试都出现问题) MS Office版本:2007 问题描述 使用OpenOffice将MS的docx文件转换为pdf文件时,docx文件 ...

  9. Qt编写数据库通用翻页demo(开源)

    在Qt与数据库结合编程的过程中,记录一多,基本上都需要用到翻页查看记录,翻页有个好处就是可以减轻显示数据的表格的压力,不需要一次性将数据库表的记录全部显示,也基本上没有谁在一页上需要一次性显示所有记录 ...

  10. SharePoint 2013 自定义翻页显示列表项

    项目需求:自定义开发一个能分页显示列表项的小部件,允许左右翻页,能根据用户权限来显示管理链接等. 效果如下: 技术要求:使用sharepoint rest API 来获取列表项,这样性能高,能够快速响 ...

随机推荐

  1. 第132篇:npm第一次使用自己的包(package-lock.json、package.json文件作用说明)

    好家伙,   1.新建一个文件夹,命名为test   2.下载包 npm i panghu-planebattle   空白的文件夹中多了两个文件 package-lock.json和package. ...

  2. 【Azure Developer】CURL 发送Oauth2 Token请求获取到 404 Not Found 问题

    问题描述 当使用 Postman 向AAD 发送如下请求时候,得到了404 Not Found的错误. "curl --location --request POST 'https://lo ...

  3. require和import的区别以及相互使用的方式

    Node.js 里可分为 CommonJS 模块和 ECMAScript 模块(ESM)两种不同的模块系统. CommonJS 模块是 Node.js 最初支持的模块系统,它使用 require() ...

  4. C++基本知识梳理

    一.命名空间 概念:命名空间是新定义的一个作用域,里面可以放函数,变量,定义类等,主要用来防止命名冲突. 实现:namespace关键字 命名空间名字{ 命名空间成员 } 注意点: 1.命名空间可以嵌 ...

  5. harbor 安装

    下载地址: https://github.com/goharbor/harbor/releases?page=1 下载了多个版本,发现仅v1.10.17版本支持GC清理,所以这里安装的v1.10.17 ...

  6. 新增、修改校验逻辑使用-Validation-的group分组校验完成-2022新项目

    一.业务场景 一般在项目开发中少不了新增.修改操作,这两个操作中传递的参数中也仅仅只有一个参数是不一致的,新增操作时没有ID, 修改时有ID,其校验逻辑也只有这一个ID校验的差别.最开始自己在写代码时 ...

  7. 3D模型+BI分析,打造全新的交互式3D可视化大屏开发方案

    背景介绍 在数字经济建设和数字化转型的浪潮中,数据可视化大屏已成为各行各业的必备工具.然而,传统的数据大屏往往以图表和指标为主,无法真实地反映复杂的物理世界和数据关系.为了解决这个问题,3D模型可视化 ...

  8. [VueJsDev] 其他知识 - NestJS 学习内容

    [VueJsDev] 目录列表 https://www.cnblogs.com/pengchenggang/p/17037320.html NestJS 学习内容 NestJS 学习总结 Step. ...

  9. Elasticsearch(es) 查询语句语法详解

    Elasticsearch 查询语句采用基于 RESTful 风格的接口封装成 JSON 格式的对象,称之为 Query DSL.Elasticsearch 查询分类大致分为全文查询.词项查询.复合查 ...

  10. RTMP录屏直播屏幕数据获取与MediaCodec编码

    目录 前言 RTMP直播实现流程 视频采集--MediaProjection 编码--MediaCodec 音频采集--AudioRecord RTMP音频包数据 RTMP视频数据 前言 本文介绍的是 ...