文档查看器
这是一个用于显示和打印 JSON、文本和 PDF 文件的 Widgets 应用程序。
文档查看器 展示了如何使用带有静态和动态工具栏、菜单和动作的 QMainWindow。此外,它还在基于小部件的应用程序中展示以下功能:
- 使用 QSettings 查询和保存用户偏好,并管理之前打开的文件历史记录。
- 控制鼠标悬停在工具上时的光标行为。
- 创建动态加载的插件。
创建应用程序及其主窗口
应用程序及其主窗口在 main.cpp
中构建。main() 函数使用 QCommandLineParser 处理命令行参数 - 帮助、版本 和可选的位置参数,文件。如果用户在启动应用程序时提供了文件的路径,则主窗口会打开它。
int main(int argc, char *argv[]) { QApplication app(argc, argv); QCoreApplication::setOrganizationName("QtProject"_L1); QCoreApplication::setApplicationName("DocumentViewer"_L1); QCoreApplication::setApplicationVersion("1.0"_L1); QCommandLineParser parser; parser.setApplicationDescription(QApplication::translate("main", "A viewer for JSON, PDF and text files")); parser.addHelpOption(); parser.addVersionOption(); parser.addPositionalArgument("File"_L1, QApplication::translate("main", "JSON, PDF or text file to open")); parser.process(app); const QStringList &positionalArguments = parser.positionalArguments(); const QString &fileName = (positionalArguments.count() > 0) ? positionalArguments.at(0) : QString(); MainWindow w; w.show(); if (!fileName.isEmpty()) w.openFile(fileName); return app.exec(); }
主窗口类
MainWindow
类提供了一个带有菜单、动作和工具栏的应用程序屏幕。它可以打开文件,自动检测其内容类型。它还维护一个之前打开的文件列表,使用 QSettings 在启动时存储和重新加载设置。MainWindow 会为打开的文件创建一个适合的 查看器,基于其内容类型,并支持打印文档。
MainWindow 的构造函数初始化了在 Qt Designer 中创建的用户界面。 mainwindow.ui
文件在左侧提供了 QTabWidget,显示书签和缩略图。在右侧有一个 QScrollArea 用于查看文件内容。
ViewerFactory 类
ViewerFactory
类管理已知文件类型的查看器。这些查看器作为插件实现。当创建 ViewerFactory 实例时,将视图区域的主窗口指针传递给构造函数。
m_factory.reset(new ViewerFactory(ui->viewArea, this));
ViewerFactory 在构造时加载所有可用的插件。它提供了一个公共 API,用于查询已加载的插件、其名称和所支持的 MIME 类型。
using ViewerList = QList<AbstractViewer *>; QStringList viewerNames(bool showDefault = false) const; ViewerList viewers() const; AbstractViewer *findViewer(const QString &viewerName) const; AbstractViewer *defaultViewer() const; QStringList supportedMimeTypes() const;
viewer()
函数返回一个指向适合打开作为参数传递的 QFile 的插件的指针。
m_viewer = m_factory->viewer(file);
如果应用程序设置包含查看器的部分,则将其传递到查看器的虚拟 restoreState()
函数中。
void MainWindow::restoreViewerSettings() { if (!m_viewer) return; QSettings settings; settings.beginGroup(settingsViewers); QByteArray viewerSettings = settings.value(m_viewer->viewerName(), QByteArray()).toByteArray(); settings.endGroup(); if (!viewerSettings.isEmpty()) m_viewer->restoreState(viewerSettings); }
然后,将标准 UI 资产传递给查看器,并将主滚动区域设置为显示查看器的显示小部件。
m_viewer->initViewer(ui->actionBack, ui->actionForward, ui->menuHelp->menuAction(), ui->tabWidget); restoreViewerSettings(); ui->scrollArea->setWidget(m_viewer->widget()); return true; }
AbstractViewer 类
AbstractViewer
提供了查看、保存和打印文档的通用 API。可以查询文档和查看器的属性。
- 文档是否有内容?
- 它是否已修改?
- 是否支持概览(缩略图或书签)?
AbstractViewer 提供了受保护的方法,供派生类在主窗口上创建操作和菜单。为了在主窗口上显示这些资产,它们被绑定到它。AbstractViewer 负责移除和销毁它创建的 UI 资产。它通过继承 QObject 来实现信号和槽。
信号
void uiInitialized();
此信号在查看器接收到与主窗口上的 UI 资产相关的所有必要信息后发出。
void printingEnabledChanged(bool enabled);
当文档打印被启用或禁用时,此信号发出。这在新文档成功加载后发生,或者例如,所有内容被移除后。
void printStatusChanged(AbstractViewer::PrintStatus status);
开始打印过程后,此信号通知其进度变化。
void documentLoaded(const QString &fileName);
此信号通知应用程序已成功加载文档。
TxtViewer 类
TxtViewer
是一个简单的文本查看器,继承自 AbstractViewer。它支持编辑文本文件、复制/剪切和粘贴、打印以及保存更改。
JsonViewer 类
JsonViewer
在 QTreeView 中显示 JSON 文件。内部,它将文件的 内容加载到一个 QJsonDocument 中,并使用它来填充一个由 JsonItemModel
创建的自定义树模型。
JSON 查看器插件演示了如何实现从 QAbstractItemModel 继承的自定义项模型。 JsonTreeItem
类提供一个基本的 API 用于操作 JSON 数据并将其传播回底层的 QJsonDocument。
JsonViewer 使用文档的顶级对象作为导航的书签。其他节点(键和值)可以作为额外的书签添加,或从书签列表中删除。使用 QLineEdit 作为搜索字段来在 JSON 树中导航。
PdfViewer 类
PdfViewer
类(和插件)是 PDF 查看器小部件示例 的一个分支。它演示了使用 QScroller 来流畅地翻阅文档的使用。
其他相关类
HoverWatcher 类
HoverWatcher
类在鼠标悬停在窗口小部件上时设置一个重写光标,并在鼠标离开时恢复。为了防止为同一窗口小部件创建多个 HoverWatcher 实例,它按照窗口小部件实施为单例。
HoverWatcher 继承自 QObject,它将观察的 QWidget 作为实例的父对象。它安装一个事件过滤器来拦截悬停事件而不会消费它们
HoverWatcher::HoverWatcher(QWidget *watched) : QObject(watched), m_watched(watched) { Q_ASSERT(watched); m_cursorShapes[Entered].emplace(Qt::OpenHandCursor); m_cursorShapes[MousePress].emplace(Qt::ClosedHandCursor); m_cursorShapes[MouseRelease].emplace(Qt::OpenHandCursor); // no default for Left => restore override cursor m_watched->installEventFilter(this); }
HoverAction
枚举列出了 HoverWatcher 响应的操作
enum HoverAction { Entered, MousePress, MouseRelease, Left, Ignore };
静态函数创建监控器,检查特定 QWidget 的存在,或者取消监控器
static HoverWatcher *watcher(QWidget *watched); static const HoverWatcher *watcher(const QWidget *watched); static bool hasWatcher(QWidget *widget); static void dismiss(QWidget *watched);
可以为每个 HoverAction 设置或取消设置光标形状。如果没有关联的光标形状,则当操作被触发时,应用程序的重写光标被恢复。
public slots: void setCursorShape(HoverAction type, Qt::CursorShape shape); void unSetCursorShape(HoverAction type);
mouseButtons
属性保存要考虑的鼠标按钮,用于 MousePress
操作
void setMouseButtons(Qt::MouseButtons buttons); void setMouseButton(Qt::MouseButton button, bool enable);
在处理操作后,会发出特定于操作的信号
signals: void entered(); void mousePressed(); void mouseReleased(); void left();
会发出一个通用信号,该信号将处理过的操作作为参数传递
void hoverAction(HoverAction action);
RecentFiles 类
RecentFiles
是一个用于管理最近打开的文件列表的 QStringList,它进行了特殊处理。
RecentFiles 有槽位可以一次性添加单个文件或多个文件。如果路径指向的文件存在且可以打开,那么它会添加到最近文件的列表中。如果文件已经在列表中,它会从原来位置移除并添加到顶部。
public slots: void addFile(const QString &fileName) { addFile(fileName, EmitPolicy::EmitWhenChanged); } void addFiles(const QStringList &fileNames);
可以通过名称或索引删除列表中的文件。
void removeFile(const QString &fileName) { removeFile(m_files.indexOf(fileName)); } void removeFile(qsizetype index) {removeFile(index, RemoveReason::Other); }
实现了从 QSettings 中保存和恢复的槽位。
void saveSettings(QSettings &settings, const QString &key) const; bool restoreFromSettings(QSettings &settings, const QString &key);
在恢复设置时,忽略不存在的文件。maxFiles
属性保存可存储的最近文件的最大数量(默认为 10)。
qsizetype maxFiles();
void setMaxFiles(qsizetype maxFiles);
RecentFiles
接受文件前会验证该文件是否可以读取。
RecentFileMenu 类
RecentFileMenu
是一个专门显示 RecentFiles 对象作为子菜单的 QMenu。
它的构造函数接受指向父 QObject 的指针和指向 RecentFiles 对象的指针,该对象的内容将被可视化。当用户从列表中选择最近文件时,fileOpened()
信号被触发,并将文件的绝对路径作为参数传递。
注意:RecentFileMenu
要么由其父小部件销毁,要么由传递给其构造函数的 RecentFiles
对象销毁。
© 2024 Qt 公司有限公司。包含在此的文档贡献由其各自的所有者享有版权。提供的文档在自由软件基金会的GNU 自由文档许可版 1.3 的条款下提供。Qt 及相关标志是芬兰及其它国家 Qt 公司的注册商标。所有其他商标均为各自所有者的财产。