Qt + mupdf 显示PDF,支持翻页
使用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,支持翻页的更多相关文章
- html 打印代码,支持翻页
ylbtech_html_print html打印代码,支持翻页 <html> <head> <meta name=vs_targetSchema content=&qu ...
- flex布局构建大屏框架并支持翻页动画、滚动表格功能
本文将利用flex属性构建大屏可视化界面.界面主要分标题栏.工具栏.数据可视化窗口.其中,翻页动画以及滚动表格功能分别分布在数据可视化界面两侧. 鼠标点击标题,可看到左侧窗口翻转动画: 整体布局效 ...
- iOS:UIPageViewController翻页控制器控件详细介绍
翻页控制器控件:UIPageViewController 介绍: 1.它是为我们提供了一种类似翻书效果的一种控件.我们可以通过使用UIPageViewController控件,来完成类似图书一样的翻页 ...
- PHP.25-TP框架商城应用实例-后台2-商品列表页-搜索、翻页、排序
商品列表页 1.翻页 控制器GoodsController.class.php添加方法lst(),显示列表页 在商品模型GoodsModel.class.php类中添加search方法 /** *实现 ...
- 转:在 C# 中使用 P/Invoke 调用 Mupdf 函数库显示 PDF 文档
在 C# 中使用 P/Invoke 调用 Mupdf 函数库显示 PDF 文档 一直以来,我都想为 PDF 补丁丁添加一个 PDF 渲染引擎.可是,目前并没有可以在 .NET 框架上运行的免费 PDF ...
- Qt仿Android带特效的数字时钟源码分析(滑动,翻页,旋转效果)
这个数字时钟的源码可以在Qt Demo中找到,风格是仿Android的,不过该Demo中含有三种动画效果(鉴于本人未曾用过Android的系统,因此不知道Android的数字时钟是否也含有这三种效果) ...
- 自己定义 ViewGroup 支持无限循环翻页之三(响应回调事件)
大家假设喜欢我的博客,请关注一下我的微博,请点击这里(http://weibo.com/kifile),谢谢 转载请标明出处,再次感谢 ################################ ...
- OpenOffice将MS docx转换成pdf文件偶数页眉不显示问题解决办法
OpenOffice版本:4.0(Windows.Linux下测试都出现问题) MS Office版本:2007 问题描述 使用OpenOffice将MS的docx文件转换为pdf文件时,docx文件 ...
- Qt编写数据库通用翻页demo(开源)
在Qt与数据库结合编程的过程中,记录一多,基本上都需要用到翻页查看记录,翻页有个好处就是可以减轻显示数据的表格的压力,不需要一次性将数据库表的记录全部显示,也基本上没有谁在一页上需要一次性显示所有记录 ...
- SharePoint 2013 自定义翻页显示列表项
项目需求:自定义开发一个能分页显示列表项的小部件,允许左右翻页,能根据用户权限来显示管理链接等. 效果如下: 技术要求:使用sharepoint rest API 来获取列表项,这样性能高,能够快速响 ...
随机推荐
- 第132篇:npm第一次使用自己的包(package-lock.json、package.json文件作用说明)
好家伙, 1.新建一个文件夹,命名为test 2.下载包 npm i panghu-planebattle 空白的文件夹中多了两个文件 package-lock.json和package. ...
- 【Azure Developer】CURL 发送Oauth2 Token请求获取到 404 Not Found 问题
问题描述 当使用 Postman 向AAD 发送如下请求时候,得到了404 Not Found的错误. "curl --location --request POST 'https://lo ...
- require和import的区别以及相互使用的方式
Node.js 里可分为 CommonJS 模块和 ECMAScript 模块(ESM)两种不同的模块系统. CommonJS 模块是 Node.js 最初支持的模块系统,它使用 require() ...
- C++基本知识梳理
一.命名空间 概念:命名空间是新定义的一个作用域,里面可以放函数,变量,定义类等,主要用来防止命名冲突. 实现:namespace关键字 命名空间名字{ 命名空间成员 } 注意点: 1.命名空间可以嵌 ...
- harbor 安装
下载地址: https://github.com/goharbor/harbor/releases?page=1 下载了多个版本,发现仅v1.10.17版本支持GC清理,所以这里安装的v1.10.17 ...
- 新增、修改校验逻辑使用-Validation-的group分组校验完成-2022新项目
一.业务场景 一般在项目开发中少不了新增.修改操作,这两个操作中传递的参数中也仅仅只有一个参数是不一致的,新增操作时没有ID, 修改时有ID,其校验逻辑也只有这一个ID校验的差别.最开始自己在写代码时 ...
- 3D模型+BI分析,打造全新的交互式3D可视化大屏开发方案
背景介绍 在数字经济建设和数字化转型的浪潮中,数据可视化大屏已成为各行各业的必备工具.然而,传统的数据大屏往往以图表和指标为主,无法真实地反映复杂的物理世界和数据关系.为了解决这个问题,3D模型可视化 ...
- [VueJsDev] 其他知识 - NestJS 学习内容
[VueJsDev] 目录列表 https://www.cnblogs.com/pengchenggang/p/17037320.html NestJS 学习内容 NestJS 学习总结 Step. ...
- Elasticsearch(es) 查询语句语法详解
Elasticsearch 查询语句采用基于 RESTful 风格的接口封装成 JSON 格式的对象,称之为 Query DSL.Elasticsearch 查询分类大致分为全文查询.词项查询.复合查 ...
- RTMP录屏直播屏幕数据获取与MediaCodec编码
目录 前言 RTMP直播实现流程 视频采集--MediaProjection 编码--MediaCodec 音频采集--AudioRecord RTMP音频包数据 RTMP视频数据 前言 本文介绍的是 ...