Qt는 메타데이터에서만 문제가 생기지 않는다면... 쉽고 빠르게 GUI 소프트웨어를 작성할 수 있는 프레임워크이죠!

소프트웨어 안에서 PDF 문서를 보여주고자 할 때도 쉽게 해결 할 수 있습니다.

 

PDF Viewer를 만들기 위한 클래스 생성 예제를 올려봅니다.

 

Qt로 작성된 poppler 라이브러리를 사용하였고, 이것은 XpdfReader 라이브러리를 기반으로 한다고 합니다.

저는 서브클래스를 만들어 확대/축소, 페이지 이동 기능만 추가하였습니다.

 

라이브러리는 https://poppler.freedesktop.org/ 에서 라이브러리를 다운받을 수 있습니다.

또는 아래에서 Visual Studio 2015 x64로 제가 빌드한 라이브러리를 다운받으실 수 있습니다.

 

poppler.zip

 

 

PDF 핸들링은 라이브러리에서 다 해주기 때문에 서브클래스는 많이 복잡하지 않습니다.

스케일 비율이 커지면 문서가 점점 짤릴텐데, 아직 마우스 드래그로 뷰를 움직이는 기능은 구현하지 않았습니다.

근데 마우스 드래그 처리가 귀찮을 뿐, Page::renderToImage 함수에서 x, y 파라미터에 값만 전달해주면 쉽게 구현할 수 있겠네요.

 

질문은 얼마든지 환영합니다.

그럼 뿅!

 

 

QDocumentWidget.h

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#pragma once
 
#include <QWidget>
#include <QLabel>
#include <QImage>
#include <QWheelEvent>
 
#include <poppler-qt5.h>
 
 
class QDocumentWidget : public QLabel
{
    Q_OBJECT
 
public:
    QDocumentWidget(QWidget* pParent = NULL);
    ~QDocumentWidget();
 
protected:
    Poppler::Document* m_pDocument;
    Poppler::Page* m_pDocPage;
    int m_page;
    int m_scale; // pdf 문서 렌더링 크기. 단위는 %.
 
protected:
    void wheelEvent(QWheelEvent* event);
    void mouseDoubleClickEvent(QMouseEvent* event);
 
public:
    bool loadDocument(std::string path);
    bool setPage(int page);
    void showDocument();
    void closeDocument();
 
};
 
cs

 

 

 

QDocumentWidget.cpp

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include "QDocumentWidget.h"
 
#include <QGuiApplication>
 
 
QDocumentWidget::QDocumentWidget(QWidget* pParent)
    : m_pDocument(nullptr)
    , m_pDocPage(nullptr)
    , m_page(0)
    , m_scale(150)
{
    setParent(pParent);
 
    setBackgroundRole(QPalette::Dark);
    setAlignment(Qt::AlignCenter);
    setAutoFillBackground(true);
    setScaledContents(false);
    setMouseTracking(true);
}
 
QDocumentWidget::~QDocumentWidget()
{
    closeDocument();
}
 
void QDocumentWidget::wheelEvent(QWheelEvent* event)
{
    Qt::KeyboardModifiers k = QGuiApplication::keyboardModifiers();
    if( k == Qt::ControlModifier )
    {
        if( event->angleDelta().y() < )
            m_scale = max(m_scale - 550);
        else
            m_scale = min(m_scale + 5500);
 
        showDocument();
    }
    else
    {
        if( event->angleDelta().y() > // 위로
            setPage(m_page - 1);
        else
            setPage(m_page + 1);
 
        showDocument();
    }
}
 
void QDocumentWidget::mouseDoubleClickEvent(QMouseEvent* event)
{
    if( event->button() == Qt::LeftButton )
    {
        m_scale = 100;
        showDocument();
    }
}
 
bool QDocumentWidget::loadDocument(std::string path)
{
    if( m_pDocument != nullptr )
        closeDocument();
 
    m_pDocument = Poppler::Document::load(path.c_str());
 
    if( m_pDocument == nullptr )
        return false;
 
    return setPage(m_page);
}
 
bool QDocumentWidget::setPage(int page)
{
    if( page < return false;
 
    if( m_pDocument )
    {
        int nPages = m_pDocument->numPages();
 
        if( page >= nPages )
            return false;
 
        m_page = page;
        m_pDocPage = m_pDocument->page(m_page);
        return m_pDocPage != nullptr;
    }
 
    return false;
}
 
void QDocumentWidget::showDocument()
{
    if!m_pDocPage )
        setPage(m_page);
 
    if( m_pDocPage )
    {
        QImage image = m_pDocPage->renderToImage(m_scale, m_scale);
        setPixmap(QPixmap::fromImage(image));
    }
}
 
void QDocumentWidget::closeDocument()
{
    if( m_pDocument != nullptr )
    {
        delete m_pDocPage;
        m_pDocPage = nullptr;
 
        delete m_pDocument;
        m_pDocument = nullptr;
    }
}
 
cs

 

 

참고 웹페이지:

[1] https://github.com/danigm/poppler

[2] http://www.xpdfreader.com/

 

'코딩 > Qt' 카테고리의 다른 글

Qt Graph 그리기  (0) 2018.07.22

+ Recent posts