持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第11天,点击查看活动详情
📒博客首页:何名取 的个人主页 - 文章 - 掘金 (juejin.cn)
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
❤️期待一起交流!
🙏作者水平很有限,如果发现错误,求告知,多谢!
🌺有问题可私信交流!!!
前言
前面已经将Qt PDF模块添加到了工程中,这意味着已经可以使用Qt PDF模块来进行PDF显示功能的开发了。本节将使用三个与PDF模块有关的类,分别是QPdfDocument-PDF文档类、PageSelector-自定义的页选择类、ZoomSelector-自定义的缩放选择类。
这三个类中QPdfDocument是Qt PDF自带的类,已经定义好了,可以直接进行使用,其余的两个类则需要利用Qt PDF模块中的一些类和其他的一些通用类来自己将其实现。
创建PageSelector类
右键点击工程文件夹,弹出菜单:
选择C++ Class来创建:
将类名设置为PageSelector,并选择基类为QWidget:
PageSelector类提供了PDF的页数操作,具有的功能有:
- 向前翻页
- 向后翻页
- 当前页数显示与跳转
- 总页数统计
改造头文件:
#ifndef PAGESELECTOR_H
#define PAGESELECTOR_H
#include <QWidget>
QT_BEGIN_NAMESPACE
class QLabel;
class QLineEdit;
class QPdfDocument;
class QPdfPageNavigation;
class QToolButton;
QT_END_NAMESPACE
class PageSelector : public QWidget
{
Q_OBJECT
public:
explicit PageSelector(QWidget *parent = nullptr); //构造页选择栏
void setPageNavigation(QPdfPageNavigation *pageNavigation); //设置pdf导航栏
private slots:
void onCurrentPageChanged(int page); //当前页切换
void pageNumberEdited(); //页跳转
private:
QPdfPageNavigation *m_pageNavigation;
QLineEdit *m_pageNumberEdit; //当前页数
QLabel *m_pageCountLabel; //总页数
QToolButton *m_previousPageButton; //上一页
QToolButton *m_nextPageButton; //下一页
};
#endif // PAGESELECTOR_H
源文件中的构造函数和其他函数实现:
#include "pageselector.h"
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPdfPageNavigation>
#include <QToolButton>
PageSelector::PageSelector(QWidget *parent)
: QWidget(parent)
, m_pageNavigation(nullptr)
{
//水平排列
QHBoxLayout *layout = new QHBoxLayout(this);
//向上翻页
m_previousPageButton = new QToolButton(this);
m_previousPageButton->setText("<");
m_previousPageButton->setEnabled(false);
//当前页数
m_pageNumberEdit = new QLineEdit(this);
m_pageNumberEdit->setAlignment(Qt::AlignRight);
//页数统计
m_pageCountLabel = new QLabel(this);
m_pageCountLabel->setText("0");
//向后翻页
m_nextPageButton = new QToolButton(this);
m_nextPageButton->setText(">");
m_nextPageButton->setEnabled(false);
//向布局中添加组件
layout->addWidget(m_previousPageButton);
layout->addWidget(m_pageNumberEdit);
layout->addWidget(m_pageCountLabel);
layout->addWidget(m_nextPageButton);
}
void PageSelector::setPageNavigation(QPdfPageNavigation *pageNavigation)
{
m_pageNavigation = pageNavigation;
//单击向上翻页按钮,将当前页面更改为上一页
connect(m_previousPageButton, &QToolButton::clicked, m_pageNavigation, &QPdfPageNavigation::goToPreviousPage);
//返回当前页之前是否有页,如果有上一页则向上翻页按钮可以使用,否则就禁止向上翻页按钮使用
connect(m_pageNavigation, &QPdfPageNavigation::canGoToPreviousPageChanged, m_previousPageButton, &QToolButton::setEnabled);
//当前页码属性与页码输入栏绑定
connect(m_pageNavigation, &QPdfPageNavigation::currentPageChanged, this, &PageSelector::onCurrentPageChanged);
//总页数与显示总页数的标签绑定
connect(m_pageNavigation, &QPdfPageNavigation::pageCountChanged, this, [this](int pageCount){ m_pageCountLabel->setText(QString::fromLatin1("/ %1").arg(pageCount)); });
//当前页码输入与页码跳转绑定
connect(m_pageNumberEdit, &QLineEdit::editingFinished, this, &PageSelector::pageNumberEdited);
//单击向下翻页按钮,将当前页面更改为下一页
connect(m_nextPageButton, &QToolButton::clicked, m_pageNavigation, &QPdfPageNavigation::goToNextPage);
//返回当前页之后是否有页,如果有下一页则下上翻页按钮可以使用,否则就禁止向下翻页按钮使用
connect(m_pageNavigation, &QPdfPageNavigation::canGoToNextPageChanged, m_nextPageButton, &QToolButton::setEnabled);
//设置当前页码
onCurrentPageChanged(m_pageNavigation->currentPage());
}
void PageSelector::onCurrentPageChanged(int page)
{
if (m_pageNavigation->pageCount() == 0)
m_pageNumberEdit->setText(QString::number(0));
else
m_pageNumberEdit->setText(QString::number(page + 1));
}
void PageSelector::pageNumberEdited()
{
if (!m_pageNavigation)
return;
const QString text = m_pageNumberEdit->text();
//将输入数字字符串转换为int类型
bool ok = false;
const int pageNumber = text.toInt(&ok);
if (!ok)
onCurrentPageChanged(m_pageNavigation->currentPage());
else
m_pageNavigation->setCurrentPage(qBound(0, pageNumber - 1, m_pageNavigation->pageCount() - 1));
}
创建ZoomSelector类
ZoomSelector类创建步骤与PageSelector类的创建步骤基本类似,不同的是ZoomSelector类的基类选择为QComboBox:
ZoomSelector类提供了PDF页面缩放的操作,具体功能有:
- 按照最大宽度填充
- 按照最大页面填充
- 百分比填充
- 放大
- 缩小
改造头文件:
#ifndef ZOOMSELECTOR_H
#define ZOOMSELECTOR_H
#include <QComboBox>
#include <QPdfView>
class ZoomSelector : public QComboBox
{
Q_OBJECT
public:
explicit ZoomSelector(QWidget *parent = nullptr); //构造页面大小选择栏
public slots:
void setZoomFactor(qreal zoomFactor); //设置缩放比例
void reset(); //重置页面缩放比例
signals:
void zoomModeChanged(QPdfView::ZoomMode zoomMode); //更改缩放模式
void zoomFactorChanged(qreal zoomFactor); //更改缩放比例
private slots:
void onCurrentTextChanged(const QString &text); //当前缩放比例
};
#endif // ZOOMSELECTOR_H
源文件中的构造函数和其他函数实现:
#include "zoomselector.h"
#include <QLineEdit>
ZoomSelector::ZoomSelector(QWidget *parent)
: QComboBox(parent)
{
setEditable(true);
//添加多种缩放模式
addItem(QLatin1String("Fit Width"));
addItem(QLatin1String("Fit Page"));
addItem(QLatin1String("12%"));
addItem(QLatin1String("25%"));
addItem(QLatin1String("33%"));
addItem(QLatin1String("50%"));
addItem(QLatin1String("66%"));
addItem(QLatin1String("75%"));
addItem(QLatin1String("100%"));
addItem(QLatin1String("125%"));
addItem(QLatin1String("150%"));
addItem(QLatin1String("200%"));
addItem(QLatin1String("400%"));
//将缩放选择栏与缩放响应函数绑定
connect(this, &QComboBox::currentTextChanged,
this, &ZoomSelector::onCurrentTextChanged);
//将缩放比例栏输入框与缩放响应函数绑定
connect(lineEdit(), &QLineEdit::editingFinished,
this, [this](){onCurrentTextChanged(lineEdit()->text()); });
}
void ZoomSelector::setZoomFactor(qreal zoomFactor)
{
//以百分比的形式设置缩放比例
setCurrentText(QString::number(qRound(zoomFactor * 100)) + QLatin1String("%"));
}
void ZoomSelector::reset()
{
setCurrentIndex(8); // 默认缩放比例为100%
}
void ZoomSelector::onCurrentTextChanged(const QString &text)
{
if (text == QLatin1String("Fit Width")) {
emit zoomModeChanged(QPdfView::FitToWidth);
} else if (text == QLatin1String("Fit Page")) {
emit zoomModeChanged(QPdfView::FitInView);
} else {
qreal factor = 1.0;
//去掉文字框中的“%”号
QString withoutPercent(text);
withoutPercent.remove(QLatin1Char('%'));
//将文字串变为int类型
bool ok = false;
const int zoomLevel = withoutPercent.toInt(&ok);
if (ok)
factor = zoomLevel / 100.0;
emit zoomModeChanged(QPdfView::CustomZoom);
emit zoomFactorChanged(factor);
}
}