Qt下PDF阅读器的开发

目前linux 下基于Qt的PDF阅读器无外乎三种:

  • 将pdf加载到js上,利用QWebView显示
  • 基于poppler库做二次开发
  • 基于mupdf库做二次开发

第一种资料较多,要求较低,故不做详细阐述;而后两种资料相对少很多,开发难度相对而言比较大,这里仅针对后两种。

  • 基于poppler库做二次开发

首先需要去官网下载poppler库,然后解压,如果做快速开发,建议选择比较老的版本,新的版本很难找到合适的编译资料,这里我选择的是0.5.0版本。在这里你需要很多库,比如libfreetype2,fontconfig等等其他的库,我是Ubuntu 16.04,可能是因为源,部分库找不到,不得已只能去下载官网源码,自行编译和安装。

编译选项中最好设定自己的安装路径,这样无论是交叉编译还是最后程序的链接都比较透明,我这里都生成在out目录

稍早的版本中API也比较少,开发过程中,看起来更清楚。

这里包含的头文件是相当少的,每个头文件包含的内容也不多。

程序部分我看了网上的例子,然后自己做了部分修改:

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QImage>
#include <QLabel>
#include <QPushButton>

#include "poppler/cpp/poppler-document.h"
#include "poppler/cpp/poppler-image.h"
#include "poppler/cpp/poppler-rectangle.h"
#include "poppler/cpp/poppler-embedded-file.h"
#include "poppler/cpp/poppler-page.h"
#include "poppler/cpp/poppler-toc.h"
#include "poppler/cpp/poppler-font.h"
#include "poppler/cpp/poppler-page-renderer.h"
#include "poppler/cpp/poppler-version.h"
#include "poppler/cpp/poppler-global.h"
#include "poppler/cpp/poppler-page-transition.h"


class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();

    void resizeEvent(QResizeEvent *event);

    void updatePage();

public slots:
    void onPrev();
    void onNext();

    void onZoomIn();
    void onZoomOut();

private:
    int Cur_Page;
    int Total_page;
    float scale;

    QLabel* label;
    poppler::document* document;
};

#endif // WIDGET_H
#include "widget.h"
#include <QDebug>




Widget::Widget(QWidget *parent)
    : QWidget(parent),
      Cur_Page(0)
{
    int numPages = 0;
    scale = 1;

    document = poppler::document::load_from_file("a.pdf");

    Total_page = document->pages();
    qDebug() << "PDF pages: " << numPages;



    label = new QLabel(this);
    label->setGeometry(0,0,1024,600);


    label->setAlignment(Qt::AlignCenter);
    //label->setPixmap(QPixmap::fromImage(qimage));
    label->setVisible(true);

    QPushButton* prevBtn = new QPushButton(this);
    prevBtn->setText("Prev");
    prevBtn->setGeometry(910, 240, 60,100);
    connect( prevBtn, SIGNAL(pressed()), this, SLOT(onPrev()));
    QPushButton* nextBtn = new QPushButton(this);
    nextBtn->setText("Next");
    nextBtn->setGeometry(910, 340, 60,100);
    connect( nextBtn, SIGNAL(pressed()), this, SLOT(onNext()));


    QPushButton* plusBtn = new QPushButton(this);
    plusBtn->setText("+");
    plusBtn->setGeometry(910, 50, 20, 20);
    connect( plusBtn, SIGNAL(pressed()), this, SLOT(onZoomIn()));
    QPushButton* minBtn = new QPushButton(this);
    minBtn->setText("-");
    minBtn->setGeometry(940, 50, 20, 20);
    connect( minBtn, SIGNAL(pressed()), this, SLOT(onZoomOut()));
    updatePage();

}

Widget::~Widget()
{

}

void Widget::resizeEvent(QResizeEvent *event)
{
    this->setGeometry(0,0,1024,600);
}


void Widget::updatePage()
{
    poppler::page_renderer* render = new poppler::page_renderer();
    //render->set_render_hint(poppler::page_renderer::render_hint::antialiasing);
    //render->set_render_hint(poppler::page_renderer::render_hint::text_antialiasing);


    render->set_render_hints(poppler::page_renderer::render_hint::antialiasing |
                             poppler::page_renderer::render_hint::text_antialiasing
                             );

    poppler::page* page = document->create_page(Cur_Page);

    poppler::image image = render->render_page(page, 72, 72, -1,-1,-1, -1);
    qDebug() << "image format: " << image.format();

    int width = render->render_page(page).width();
    int height = render->render_page(page).height();
    qDebug() << "width: " << width;
    qDebug() << "height: " << height;

    qDebug()<< "scale: "<< scale * 100 << "\%";
    QImage qimage((uchar*)image.data(), width, height, QImage::Format::Format_ARGB32);
    qDebug() << "image format: "<<qimage.format();
    label->setPixmap(QPixmap::fromImage(qimage.scaledToWidth(width*scale)));

}


void Widget::onPrev()
{
    if(Cur_Page == 0)
        Cur_Page = 0;
    else
        Cur_Page--;
   //load page
    updatePage();
}

void Widget::onNext()
{
    if(Cur_Page == Total_page -1)
        Cur_Page = Total_page -1;
    else
        Cur_Page++;
    //load page
    updatePage();
}

void Widget::onZoomIn()
{
    scale += 0.15;
    updatePage();
}

void Widget::onZoomOut()
{
    scale -= 0.15;
    updatePage();
}

显示效果如下:

猜你喜欢

转载自blog.csdn.net/k_wang_/article/details/82869791