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

相关推荐
锦亦之22337 小时前
QT+OSG+OSG-earth如何在窗口显示一个地球
开发语言·qt
柳鲲鹏10 小时前
编译成功!QT/6.7.2/Creator编译Windows64 MySQL驱动(MinGW版)
开发语言·qt·mysql
三玖诶10 小时前
如何在 Qt 的 QListWidget 中逐行添加和显示数据
开发语言·qt
阳光开朗_大男孩儿16 小时前
DBUS属性原理
linux·服务器·前端·数据库·qt
Alphapeople18 小时前
Qt Modbus
开发语言·qt
竹林海中敲代码18 小时前
Qt Creator 集成开发环境 常见问题
qt·qt工具常见问题
竹林海中敲代码21 小时前
Qt安卓开发连接手机调试(红米K60为例)
android·qt·智能手机
长沙红胖子Qt1 天前
关于 Qt运行加载内存较大崩溃添加扩大运行内存 的解决方法
开发语言·qt·qt扩大运行内存
gopher95111 天前
qt相关面试题
开发语言·qt·面试
三玖诶1 天前
在 Qt 中使用 QLabel 设置 GIF 动态背景
开发语言·qt·命令模式