Qt는 메타데이터에서만 문제가 생기지 않는다면... 쉽고 빠르게 GUI 소프트웨어를 작성할 수 있는 프레임워크이죠!
소프트웨어 안에서 PDF 문서를 보여주고자 할 때도 쉽게 해결 할 수 있습니다.
PDF Viewer를 만들기 위한 클래스 생성 예제를 올려봅니다.
Qt로 작성된 poppler 라이브러리를 사용하였고, 이것은 XpdfReader 라이브러리를 기반으로 한다고 합니다.
저는 서브클래스를 만들어 확대/축소, 페이지 이동 기능만 추가하였습니다.
라이브러리는 https://poppler.freedesktop.org/ 에서 라이브러리를 다운받을 수 있습니다.
또는 아래에서 Visual Studio 2015 x64로 제가 빌드한 라이브러리를 다운받으실 수 있습니다.
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() < 0 )
m_scale = max(m_scale - 5, 50);
else
m_scale = min(m_scale + 5, 500);
showDocument();
}
else
{
if( event->angleDelta().y() > 0 ) // 위로
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 < 0 ) 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 |
---|