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 | 
|---|
 poppler.zip
poppler.zip