- 引入头文件
#include <QTreeView>
#include <QStandardItemModel>
#include <poppler/qt5/poppler-qt5.h>
- 创建一个 QTreeView 和 Poppler::Document 对象
QTreeView *treeView = new QTreeView(this);
Poppler::Document *document = Poppler::Document::load(inputFilePath);
- 获取文档的页面数量和每个页面的链接信息
int pageCount = document->numPages();
for (int i = 0; i < pageCount; i++) {
Poppler::Page *page = document->page(i);
QList<Poppler::LinkDestination *> linkDestinations = page->linkDestinations();
for (int j = 0; j < linkDestinations.size(); j++) {
Poppler::LinkDestination *destination = linkDestinations.at(j);
QString label = destination->title();
int pageNum = destination->page()-1;
QRectF rect = destination->linkArea();
// 将菜单项添加到 QTreeView 中
QStandardItem *item = new QStandardItem(QString("%1").arg(label));
item->setData(pageNum, Qt::UserRole);
item->setData(rect.top(), Qt::UserRole + 1);
treeModel->setItem(i, item);
}
delete page;
}
- 在 QTreeView 上注册信号槽函数,处理用户点击菜单项的事件
connect(treeView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(onTreeItemClicked(const QModelIndex &)));
- 在槽函数中获取当前选中的菜单项的页码和位置信息,并将视图滚动到该位置
void onTreeItemClicked(const QModelIndex &index) {
int pageNum = index.data(Qt::UserRole).toInt();
qreal yPos = index.data(Qt::UserRole + 1).toReal();
Poppler::Page *page = document->page(pageNum);
QRectF pageRect = page->pageSize();
delete page;
qreal dpiScaleFactor = QApplication::desktop()->logicalDpiX() / 72.0;
int y = static_cast<int>(yPos * dpiScaleFactor);
QScrollBar *scrollBar = pdfView->verticalScrollBar();
scrollBar->setValue(y);
}
完整示例代码:
#include <QTreeView>
#include <QStandardItemModel>
#include <poppler/qt5/poppler-qt5.h>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr)
: QMainWindow(parent)
{
QTreeView *treeView = new QTreeView(this);
setCentralWidget(treeView);
QString inputFilePath = "example.pdf";
Poppler::Document *document = Poppler::Document::load(inputFilePath);
if (!document || document->isLocked()) {
return;
}
QStandardItemModel *treeModel = new QStandardItemModel(document->numPages(), 1, this);
treeModel->setHeaderData(0, Qt::Horizontal, tr("Table of Contents"));
treeView->setModel(treeModel);
int pageCount = document->numPages();
for (int i = 0; i < pageCount; i++) {
Poppler::Page *page = document->page(i);
QList<Poppler::LinkDestination *> linkDestinations = page->linkDestinations();
for (int j = 0; j < linkDestinations.size(); j++) {
Poppler::LinkDestination *destination = linkDestinations.at(j);
QString label = destination->title();
int pageNum = destination->page()-1;
QRectF rect = destination->linkArea();
QStandardItem *item = new QStandardItem(QString("%1").arg(label));
item->setData(pageNum, Qt::UserRole);
item->setData(rect.top(), Qt::UserRole + 1);
treeModel->setItem(i, item);
}
delete page;
}
connect(treeView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(onTreeItemClicked(const QModelIndex &)));
}
private slots:
void onTreeItemClicked(const QModelIndex &index) {
int pageNum = index.data(Qt::UserRole).toInt();
qreal yPos = index.data(Qt::UserRole + 1).toReal();
Poppler::Document *document = Poppler::Document::load("example.pdf");
Poppler::Page *page = document->page(pageNum);
QRectF pageRect = page->pageSize();
delete page;
delete document;
qreal dpiScaleFactor = QApplication::desktop()->logicalDpiX() / 72.0;
int y = static_cast<int>(yPos * dpiScaleFactor);
QScrollBar *scrollBar = pdfView->verticalScrollBar();
scrollBar->setValue(y);
}
};