Qt下使用QtPdfium处理PDF文档

文章目录


前言

在我之前的文章中,有提到如何生成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图像,具体实现见下面这些代码:

1.PDFTest.pro

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文件

相关推荐
7yewh11 分钟前
嵌入式Linux QT+OpenCV基于人脸识别的考勤系统 项目
linux·开发语言·arm开发·驱动开发·qt·opencv·嵌入式linux
LostSpeed3 小时前
在福昕(pdf)阅读器中导航到上次阅读页面的方法
pdf
旭久3 小时前
SpringBoot的Thymeleaf做一个可自定义合并td的pdf表格
pdf·html·springboot
mahuifa12 小时前
混合开发环境---使用编程AI辅助开发Qt
人工智能·vscode·qt·qtcreator·编程ai
冷眼看人间恩怨12 小时前
【Qt笔记】QDockWidget控件详解
c++·笔记·qt·qdockwidget
云空16 小时前
《QT 5.14.1 搭建 opencv 环境全攻略》
开发语言·qt·opencv
小老鼠不吃猫18 小时前
力学笃行(二)Qt 示例程序运行
开发语言·qt
晓纪同学19 小时前
QT创建一个模板槽和信号刷新UI
开发语言·qt·ui
爱码小白21 小时前
PyQt5 学习方法之悟道
开发语言·qt·学习方法
神色自若1 天前
Net9为PDF文字替换,使用Spire.PDF版本10.12.4.1360
pdf