文章目录
- [1. 技术平台](#1. 技术平台)
- [2. Qt pdf 模块](#2. Qt pdf 模块)
- [3. cmake 使用模块](#3. cmake 使用模块)
- [4. 许可证](#4. 许可证)
- [5. 简单示例](#5. 简单示例)
-
- [5.1 CMakeLists.txt](#5.1 CMakeLists.txt)
- [5.2 main.cpp](#5.2 main.cpp)
- [6. 总结](#6. 总结)
1. 技术平台
项目 | 说明 |
---|---|
OS | win10 x64 |
Qt | 6.6 |
compiler | msvc2022 |
构建工具 | cmake |
2. Qt pdf 模块
Qt PDF模块包含用于呈现PDF文档的类和函数。
- QPdfDocument 类加载PDF文档,并根据QPdfDocumentRenderOptions类提供的选项从中呈现页面。
- QPdfPageRenderer 类管理一个队列,该队列收集所有呈现请求。
- QPdfPageNavigator 类处理通过PDF文档的导航。
- QPdfSearchModel 类搜索字符串并保存搜索结果。
- QPdfBookmarkModel 类保存目录(如果存在)。
- QPdfLinkModel 保存有关页面上超链接的信息。
- QPdfView 小部件是一个完整的PDF查看器,< PDF Viewer Widget Example> 示例展示了如何使用它。
Qt Quick 部分略过不提
如果只需要呈现页面图像,而不需要文本选择、搜索和导航等功能,则该模块包含一个QImageIOHandler插件,该插件将PDF视为可伸缩的图像格式,类似于SVG。您可以简单地使用Image,并将currentFrame属性设置为希望显示的页面索引。如果PDF文件不呈现其自己的背景,则图像具有透明背景。
3. cmake 使用模块
cpp
find_package(Qt6 REQUIRED COMPONENTS Pdf PdfWidgets)
target_link_libraries(mytarget Qt6::Pdf Qt6::PdfWidgets)
4. 许可证
Qt PDF在Qt公司的商业许可下可用。此外,它在GNU较宽松通用公共许可证(版本3)或GNU通用公共许可证(版本2)下可用。有关此模块的更多详细信息,请参阅Qt PDF许可。
5. 简单示例
5.1 CMakeLists.txt
cpp
#CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(QtPDF VERSION 0.1 LANGUAGES CXX)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets PdfWidgets Pdf)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets PdfWidgets Pdf)
set(PROJECT_SOURCES
main.cpp
)
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
qt_add_executable(QtPDF
MANUAL_FINALIZATION
${PROJECT_SOURCES}
)
# Define target properties for Android with Qt 6 as:
# set_property(TARGET QtPDF APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
# ${CMAKE_CURRENT_SOURCE_DIR}/android)
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
else()
if(ANDROID)
add_library(QtPDF SHARED
${PROJECT_SOURCES}
)
# Define properties for Android with Qt 5 after find_package() calls as:
# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
else()
add_executable(QtPDF
${PROJECT_SOURCES}
)
endif()
endif()
target_link_libraries(QtPDF PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::PdfWidgets
Qt${QT_VERSION_MAJOR}::Pdf
)
# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an
# explicit, fixed bundle identifier manually though.
if(${QT_VERSION} VERSION_LESS 6.1.0)
set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.QtPDF)
endif()
set_target_properties(QtPDF PROPERTIES
${BUNDLE_ID_OPTION}
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)
include(GNUInstallDirs)
install(TARGETS QtPDF
BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
if(QT_VERSION_MAJOR EQUAL 6)
qt_finalize_executable(QtPDF)
endif()
5.2 main.cpp
cpp
#include <QtWidgets>
#include <QtPdfWidgets>
#include "qout.hpp"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QMainWindow w;
// 分割器
auto splitter = new QSplitter(&w);
w.setCentralWidget(splitter);
// PDF查看器控件
auto *pdf_view = new QPdfView(splitter);
pdf_view->setPageMode(QPdfView::PageMode::MultiPage); // 多页浏览模式
pdf_view->setZoomMode(QPdfView::ZoomMode::FitToWidth);// 适合宽度模式
// QPdfDocument类 加载PDF文档并呈现页面
auto pdf_doc = new QPdfDocument(pdf_view);
pdf_view->setDocument(pdf_doc);
pdf_doc->load("E:/00_Download/Compressed/现代 C 教程:高速上手 C 11_14_17_20.pdf");
// QPdfBookmarkModel类 保存PDF文档中的链接树(锚点),例如目录。
QPdfBookmarkModel *pdfBookmarkModel = new QPdfBookmarkModel(splitter);
pdfBookmarkModel->setDocument(pdf_doc);
// 使用TreeView 来显示目录
auto bookMarkTreeView = new QTreeView(splitter);
QFont serifFont("Times", 10, QFont::Normal);
bookMarkTreeView->setModel(pdfBookmarkModel);
bookMarkTreeView->setFont(serifFont);
bookMarkTreeView->header()->hide();
splitter->addWidget(bookMarkTreeView);
splitter->addWidget(pdf_view);
splitter->setStretchFactor(1,1); // pdf_view 获取最大的可用空间
w.showMaximized();
// 打印书签的角色名称
qout << pdfBookmarkModel->roleNames();
qout << pdfBookmarkModel->rowCount() << pdfBookmarkModel->columnCount();
auto index = pdfBookmarkModel->index(0,0);
qout << index;
qout << pdfBookmarkModel->data(index,(int)QPdfBookmarkModel::Role::Title);
qout << pdfBookmarkModel->data(index,(int)QPdfBookmarkModel::Role::Level);
qout << pdfBookmarkModel->data(index,(int)QPdfBookmarkModel::Role::Page);
qout << pdfBookmarkModel->data(index,(int)QPdfBookmarkModel::Role::Location);
qout << pdfBookmarkModel->data(index,(int)QPdfBookmarkModel::Role::Zoom);
QObject::connect(bookMarkTreeView,&QTreeView::clicked,bookMarkTreeView,[pdf_view,pdfBookmarkModel](const QModelIndex &index){
QPdfPageNavigator* nav = pdf_view->pageNavigator();
auto page = pdfBookmarkModel->data(index,(int)QPdfBookmarkModel::Role::Page).toInt();
nav->jump(page, {}, nav->currentZoom());
});
return a.exec();
}
6. 总结
Qt pdf 模块 底层使用的是PDFium库, 不知道是不是PDFium库的版本问题,在解析书签目录的时候,还是有点问题, 没有location,所以没必要深究这个模块,不是太理想