A Qt Quick PDF viewer that views one page at a time.
PDF Single Page Viewer Example 演示如何使用 PdfScrollablePageView component to render PDF documents and search for text in them.
要运行范例从 Qt Creator ,打开 欢迎 模式,然后选择范例从 范例 。更多信息,拜访 构建和运行范例 .
Instantiate an ApplicationWindow , bind its title to the title of the PDF document, and create a toolbar:
ApplicationWindow { id: root width: 800 height: 1024 color: "lightgrey" title: document.title visible: true required property url source // for main.cpp property real scaleStep: Math.sqrt(2) header: ToolBar { RowLayout { anchors.fill: parent anchors.rightMargin: 6
The toolbar has buttons for most of the common actions, plus a SpinBox to show and control the current page number:
ToolButton {
action: Action {
shortcut: StandardKey.Open
icon.source: "qrc:/singlepage/resources/document-open.svg"
onTriggered: fileDialog.open()
}
}
ToolButton {
action: Action {
shortcut: StandardKey.ZoomIn
enabled: view.sourceSize.width < 10000
icon.source: "qrc:/singlepage/resources/zoom-in.svg"
onTriggered: view.renderScale *= root.scaleStep
}
}
ToolButton {
action: Action {
shortcut: StandardKey.ZoomOut
...
SpinBox {
id: currentPageSB
from: 1
to: document.pageCount
editable: true
value: view.currentPage + 1
...
Add dialogs to inform the user when an error occurs and to prompt for a password if required:
Dialog {
id: passwordDialog
title: "Password"
standardButtons: Dialog.Ok | Dialog.Cancel
modal: true
closePolicy: Popup.CloseOnEscape
anchors.centerIn: parent
width: 300
contentItem: TextField {
id: passwordField
placeholderText: qsTr("Please provide the password")
echoMode: TextInput.Password
width: parent.width
onAccepted: passwordDialog.accept()
}
onOpened: function() { passwordField.forceActiveFocus() }
onAccepted: document.password = passwordField.text
}
Dialog {
id: errorDialog
title: "Error loading " + document.source
standardButtons: Dialog.Close
modal: true
closePolicy: Popup.CloseOnEscape
anchors.centerIn: parent
width: 300
visible: document.status === PdfDocument.Error
contentItem: Label {
id: errorField
text: document.error
}
}
添加 main 组件 PdfScrollablePageView :
PdfScrollablePageView {
id: view
anchors.fill: parent
anchors.leftMargin: searchDrawer.position * searchDrawer.width
document: PdfDocument {
id: document
source: Qt.resolvedUrl(root.source)
onPasswordRequired: passwordDialog.open()
}
searchString: searchField.text
}
A Drawer holds a ListView to show search results from the searchModel :
Drawer {
id: searchDrawer
edge: Qt.LeftEdge
// modal: false
// dim: false // commented out as workaround for QTBUG-83859
width: 300
y: root.header.height
height: view.height
clip: true
ListView {
id: searchResultsList
anchors.fill: parent
anchors.margins: 2
model: view.searchModel
currentIndex: view.searchModel.currentResult
ScrollBar.vertical: ScrollBar { }
delegate: ItemDelegate {
id: resultDelegate
required property int index
required property int page
required property string contextBefore
required property string contextAfter
width: parent ? parent.width : 0
RowLayout {
anchors.fill: parent
spacing: 0
Label {
text: "Page " + (resultDelegate.page + 1) + ": "
}
Label {
text: resultDelegate.contextBefore
elide: Text.ElideLeft
horizontalAlignment: Text.AlignRight
Layout.fillWidth: true
Layout.preferredWidth: parent.width / 2
}
Label {
font.bold: true
text: view.searchString
width: implicitWidth
}
Label {
text: resultDelegate.contextAfter
elide: Text.ElideRight
Layout.fillWidth: true
Layout.preferredWidth: parent.width / 2
}
}
highlighted: ListView.isCurrentItem
onClicked: view.searchModel.currentResult = resultDelegate.index
}
}
}
Finally, add a second toolbar as a footer, to hold the search field, search up/down buttons and some status information:
footer: ToolBar {
height: footerRow.implicitHeight
RowLayout {
id: footerRow
anchors.fill: parent
ToolButton {
action: Action {
icon.source: "qrc:/singlepage/resources/go-up-search.svg"
shortcut: StandardKey.FindPrevious
onTriggered: view.searchBack()
}
ToolTip.visible: enabled && hovered
ToolTip.delay: 2000
ToolTip.text: "find previous"
}
TextField {
id: searchField
placeholderText: "search"
Layout.minimumWidth: 150
Layout.maximumWidth: 300
Layout.fillWidth: true
onAccepted: searchDrawer.open()
Image {
visible: searchField.text !== ""
source: "qrc:/singlepage/resources/edit-clear.svg"
anchors {
right: parent.right
top: parent.top
bottom: parent.bottom
margins: 3
rightMargin: 5
}
TapHandler {
onTapped: searchField.clear()
}
}
}
ToolButton {
action: Action {
icon.source: "qrc:/singlepage/resources/go-down-search.svg"
shortcut: StandardKey.FindNext
onTriggered: view.searchForward()
}
ToolTip.visible: enabled && hovered
ToolTip.delay: 2000
ToolTip.text: "find next"
}
Label {
Layout.fillWidth: true
property size implicitPointSize: document.pagePointSize(view.currentPage)
text: "page " + (view.currentPage + 1) + " of " + document.pageCount +
" scale " + view.renderScale.toFixed(2) +
" original " + implicitPointSize.width.toFixed(1) + "x" + implicitPointSize.height.toFixed(1) + "pts"
visible: document.status === PdfDocument.Ready
}
}
}
}
另请参阅 PDF 多页查看器范例 .