文章目录
前言
在我之前的文章中,有提到如何生成PDF,这个可以查看文末参考文章。如果要实现在Qt下进行PDF文档的处理(读取显示),可以使用自带的PDF库以及集成一些第三方库,在这里我使用了QtPdfium(基于Pdfium的Qt封装版本)来处理PDF文档,详细内容见下文,大家可以参考学习,如有错误之处,欢迎大家批评指正。
项目效果
提示:以下是本篇文章正文内容,下面案例可供参考
一、使用QPdfDocument
在Qt中,可以使用QPdfDocument类来处理PDF文档,我目前使用的5.14.2版本,结果发现找不到这个类,查询相关资料应该在5.15版本后才有的。用这个类进行PDF的处理也是比较好用的,由于我目前版本不支持,所有就没使用这种方法,如何使用可见这篇文章:QT自带PDF库的使用
二、使用QtPdfium
QtPdfium是基于Pdfium的Qt封装版本,如果想要根据你当前使用的编译套件集成库,需要先对其进行相应版本的编译,对于QtPdfium的编译,可以跟着这篇文章中的步骤:qtpdfium的编译及读取pdf文件和一些简单操作
这里我使用的是MSVC_64位进行编译的,然后将生成的lib以及头文件打包放在项目同级目录下,然后在pro文件中添加下列代码(可以直接像我这样添加,也可以按照上面参考步骤中添加库进行操作)
c
INCLUDEPATH += $$PWD/qtpdfium/include
DEPENDPATH += $$PWD/qtpdfium/include
LIBS += -L$$PWD/qtpdfium/lib/ -lQt5Pdfium
三、示例完整代码
我的示例中实现了打开PDF文档,可以进行翻页显示,跳转到指定页显示,界面缩放显示以及将当前页显示的内容保存为jpg/png图像,具体实现见下面这些代码:
c
2.mainwindow.h
c
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QFileDialog>
#include <QDesktopServices>
#include <QTime>
#include <QImage>
#include <QPixmap>
#include <QWheelEvent>
#include <QDebug>
#include "qpdfium.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void initWidget();
void showPdfData(int curPage);
void updateScaledPixmap();
protected:
void wheelEvent(QWheelEvent *event) override;
private slots:
void on_pb_open_clicked();
void on_pb_previous_clicked();
void on_pb_next_clicked();
void on_pb_saveImage_clicked();
void on_pb_viewImage_clicked();
void on_le_assignPage_editingFinished();
private:
Ui::MainWindow *ui;
int m_curPage; //当前页
int m_totalPage; //总页数
double m_zoomScale; //缩放比例
bool m_validFlag; //打开pdf是否有效
QString m_saveImagePath; //图像保存路径
QPixmap m_showPixmap; //界面显示图像
QPdfium *m_pdfium; //QPdfium对象
};
#endif // MAINWINDOW_H
3.mainwindow.cpp
c
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->initWidget();
}
MainWindow::~MainWindow()
{
delete ui;
}
//初始化界面
void MainWindow::initWidget()
{
//初始化变量
m_curPage = 0;
m_totalPage = 0;
m_zoomScale = 1.0;
m_validFlag = false;
m_saveImagePath = "";
m_showPixmap = QPixmap();
//实例化QPdfium对象
m_pdfium = new QPdfium();
//exe运行目录下创建保存图像的文件夹
QString exePath = QCoreApplication::applicationDirPath();
m_saveImagePath = exePath + "/保存图像/";
QDir dstDir(m_saveImagePath);
if(!dstDir.exists())
{
if(!dstDir.mkpath(m_saveImagePath))
{
qDebug()<<m_saveImagePath<<"文件夹创建失败!";
}
}
}
//显示指定页内容
void MainWindow::showPdfData(int curPage)
{
QPdfiumPage pdfiumPage = m_pdfium->page(curPage);
QImage image = pdfiumPage.image();
m_showPixmap = QPixmap::fromImage(image).scaled(ui->lb_image->size(),
Qt::IgnoreAspectRatio,Qt::SmoothTransformation); //IgnoreAspectRatio:填满 KeepAspectRatio:保持比例
ui->lb_image->setPixmap(m_showPixmap);
QString text = pdfiumPage.text();
qDebug()<<"第"<<curPage+1<<"PDF文本内容:"<<text;
//刷新当前页
ui->lb_curPage->setText(QString::number(curPage+1));
ui->le_assignPage->setText(QString::number(curPage+1));
}
//鼠标滚轮事件
void MainWindow::wheelEvent(QWheelEvent *event)
{
if(!m_validFlag)
{
return;
}
//根据鼠标滚轮的方向来缩放图像
const QPoint numDegrees = event->angleDelta() / 8;
const int numSteps = numDegrees.y() / 15;
if(numSteps != 0)
{
//更新缩放比例
if(numSteps > 0)
{
//放大
m_zoomScale *= 1.1;
}
else
{
//缩小,但要确保缩放比例不会小于某个最小值(比如0.1)
m_zoomScale /= 1.1;
m_zoomScale = qMax(m_zoomScale,0.1);
}
//更新缩放后的图像并显示
updateScaledPixmap();
}
}
//更新缩放图像
void MainWindow::updateScaledPixmap()
{
//计算缩放后的尺寸
QSize scaledSize = m_showPixmap.size() * m_zoomScale;
//缩放图像
QPixmap scaledPixmap = m_showPixmap.scaled(scaledSize,Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
//更新QLabel的Pixmap
ui->lb_image->setPixmap(scaledPixmap);
}
//打开文件
void MainWindow::on_pb_open_clicked()
{
QString fileName = QFileDialog::getOpenFileName(this,"打开PDF文件","D:/PDF/","PDF Files (*.pdf)");
if(!fileName.isEmpty())
{
m_pdfium->loadFile(fileName);
m_validFlag = m_pdfium->isValid();
if(m_validFlag)
{
m_totalPage = m_pdfium->pageCount();
ui->lb_totalPage->setText(QString::number(m_totalPage));
qDebug()<<"读取pdf文件页数为:"<<m_totalPage;
if(m_totalPage > 0)
{
m_curPage = 0;
showPdfData(m_curPage);
}
}
else
{
ui->lb_curPage->setText("0");
ui->lb_totalPage->setText("0");
ui->lb_image->setText("打开失败!");
}
}
else
{
m_validFlag = false;
ui->lb_curPage->setText("0");
ui->lb_totalPage->setText("0");
ui->lb_image->setText("打开失败!");
}
}
//保存图像
void MainWindow::on_pb_saveImage_clicked()
{
if(m_validFlag)
{
//以当前页数+时间组装名称
QString curPage = ui->lb_curPage->text();
QString curTime = QTime::currentTime().toString("_hhmmss");
QString imageName = m_saveImagePath + curPage + curTime;
//第一种方式:保存QPixmap到文件,这里保存为jpg格式
qDebug()<<"保存图像名:"<<imageName + ".jpg";
if(ui->lb_image->pixmap()->save(imageName + ".jpg"))
{
qDebug()<<"保存成功!";
}
else
{
qDebug()<<"保存失败!";
}
//第二种方式:保存QImage到文件,这里保存为png格式
qDebug()<<"保存图像名:"<<imageName + ".png";
QPdfiumPage pdfiumPage = m_pdfium->page(m_curPage);
QImage image = pdfiumPage.image();
if(image.save(imageName + ".png"))
{
qDebug()<<"保存成功!";
}
else
{
qDebug()<<"保存失败!";
}
}
}
//查看图像
void MainWindow::on_pb_viewImage_clicked()
{
if(!QDesktopServices::openUrl(QUrl::fromLocalFile(m_saveImagePath)))
{
qDebug()<<"存图路径打开失败!";
}
}
//上一页
void MainWindow::on_pb_previous_clicked()
{
if(m_validFlag)
{
if(m_curPage > 0)
{
m_curPage--;
}
showPdfData(m_curPage);
}
}
//下一页
void MainWindow::on_pb_next_clicked()
{
if(m_validFlag)
{
if(m_curPage < m_totalPage-1)
{
m_curPage++;
}
showPdfData(m_curPage);
}
}
//跳转到指定页
void MainWindow::on_le_assignPage_editingFinished()
{
if(m_validFlag)
{
int curPage = ui->le_assignPage->text().toInt() - 1;
if(curPage < 0)
{
m_curPage = 0;
}
else if(curPage > m_totalPage-1)
{
m_curPage = m_totalPage-1;
}
else
{
m_curPage = curPage;
}
showPdfData(m_curPage);
}
}
4.mainwindow.ui
总结
通过本文示例可以看到使用这个QtPdfium进行PDF的读取也是很简单的,显示在界面上其实就是QImage的应用。但是我在测试过程中,发现无法读取中文路径的PDF,这个问题呢我有尝试过修改编码等来进行解决,还是没有成功,看看大家有没有解决这个问题的方法呢,等待大佬的赐教,多谢!
hello:
共同学习,共同进步,如果还有相关问题,可在评论区留言进行讨论。
参考文章:
QT自带PDF库的使用
qt 使用qtpdfium实现读取pdf文件
qtpdfium的编译及读取pdf文件和一些简单操作
Qt学习:文本图片自定义拖放操作及界面打印输出PDF文件