开发环境 Qt5.5.1、Qt Creator 3.5.1
Qt实现pdf阅读器和MFC实现pdf阅读器,其实原理都是差不多的。
需要用到Poppler开源库,下载地址如下 https://poppler.freedesktop.org/
如果只是要在window的gcc下运行的话,可以下载已经编译好的库 https://sourceforge.net/projects/poppler-win32/
注意:这个是MinGW版本的Qt,也就是运行在GCC环境下的库,里面只包含 *.dll 和 *.a 。如果是Vistual Studio版本的Qt ,那么很不幸里面没有 *.lib文件。
1、新建项目,在项目的根目录新建一个“poppler”文件夹,将poppler中qt5目录下的文件都丢进去(*.h头文件,另外再将编译好的2个*.a文件和2个*.dll丢进去,我这里多丢了实现的*.cc文件,因为*.cc已经被编译成动态库了,所以可以不用包含在代码中)
2、在项目的pro配置文件中添加以下内容,引用poppler的头文件和库文件(注意:我这里是win32,所以前面加了win32前缀)
INCLUDEPATH += $$PWD/poppler win32: LIBS += -L$$PWD/poppler -llibpoppler win32: LIBS += -L$$PWD/poppler -llibpoppler-qt5
3、创建pdf工具类(该类负责与poppler库做对接,主要负责获取pdf的总页数,和每页的图像)
(1)pdfutils.h
#ifndef PDFUTILS_H #define PDFUTILS_H #include <QObject> #include <QImage> #include <QSize> #include <QDebug> #include "poppler-qt5.h" class PdfUtils { public: explicit PdfUtils(QString filePath); ~PdfUtils(); //获取指定页pdf图像(页码从0开始) QImage getPdfImage(int pageNumber); //获取pdf总页码 int getNumPages(); //获取pdf页面大小 QSize getPageSize(); private: QString filePath; int numPages; QSize pageSize; void getPdfInfo(); }; #endif // PDFUTILS_H
(2)pdfutils.cpp
#include "pdfutils.h" PdfUtils::PdfUtils(QString filePath) { this->filePath = filePath; getPdfInfo(); } PdfUtils::~PdfUtils() { } QImage PdfUtils::getPdfImage(int pageNumber) { QImage image; Poppler::Document* document = Poppler::Document::load(filePath); if (!document || document->isLocked()) { // ... error message .... delete document; return image; } // Document starts at page 0 Poppler::Page* pdfPage = document->page(pageNumber); if (pdfPage == 0) { // ... error message ... return image; } // Generate a QImage of the rendered page image = pdfPage->renderToImage(72, 72, -1, -1, -1, -1); if (image.isNull()) { // ... error message ... return image; } // after the usage, the page must be deleted delete pdfPage; delete document; return image; } int PdfUtils::getNumPages() { return numPages; } QSize PdfUtils::getPageSize() { return pageSize; } void PdfUtils::getPdfInfo() { numPages = 0; Poppler::Document* document = Poppler::Document::load(filePath); if (!document || document->isLocked()) { // ... error message .... delete document; return; } numPages = document->numPages(); Poppler::Page* pdfPage = document->page(0); pageSize = pdfPage->pageSize(); qDebug()<<pageSize; delete pdfPage; delete document; }
4、pdf显示类(pdf的右侧显示滚动条,①拖动滚动条翻页 ②鼠标拖动pdf到最上或最底时翻页)
注意:本文省略了页面缓存,如果是真实的项目的话,本着严谨的态度,请务必缓存页面
(1)mypdfcanvas.h(继承父类的resizeEvent是为了 ①当pdf只有1页时不显示滚动条 ②当用户拖动缩放窗口时动态改变pdf显示尺寸)
#ifndef MYPDFCANVAS_H #define MYPDFCANVAS_H #include <QWidget> #include <QVector> #include <QMouseEvent> #include <QPaintEvent> #include <QPainter> #include <QPaintEvent> #include <QMap> #include <QPalette> #include <QResizeEvent> #include "pdfutils.h" class MyPdfCanvas : public QWidget { Q_OBJECT public: explicit MyPdfCanvas(QWidget *parent = 0); ~MyPdfCanvas(); void resizeEvent(QResizeEvent* e); void paintEvent(QPaintEvent *e); void mousePressEvent(QMouseEvent *e); void mouseReleaseEvent(QMouseEvent *e); void mouseMoveEvent(QMouseEvent *e); void setMaxCachedNum(int maxCachedNum); //如果不能解析pdf返回false bool setPath(QString pdfPath); //页码从0开始 bool setPage(int pageNumber); //获取页数 int getNumPages(); float getScaledRatio(); //显示裁剪后的图片 bool showClipImage(int pageNumber, int x, int y, int w, int h); //取消显示裁剪图片,恢复正常显示 void cancelClip(); //实际获取的pdf宽高度 QSize pdfActualSize; signals: void pageChanged(int currentPage); private: PdfUtils* pdfUtils; QString pdfPath; //最大缓存图片数量 int maxCachedNum; //用来缓存pdf的每一个页面的图像(从0开始) QMap<int, QImage> cachedImageMap; //用来存储已缓存的pdf页面序号(从0开始) // QQueue<int> cachedPageQueue; //当前页码(从0开始) int currentPage; //总页码(从0开始) int numPages; bool isMouseDown; int lastMouseY; //当前pdf页面的图像 QImage image; int imageX; int imageY; int imageMinY; //是否是剪裁状态 bool isClip; //获取指定页的图片 bool getPdfImage(int pageNumber); void reachTop(); void reachBottom(); //判断是否需要发送重定位签名框的信号 void needLocateSignArea(); }; #endif // MYPDFCANVAS_H
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/482233.html