Implement a PDF Viewer Dialog
This is based on the example in pyside6 changed to use a QDialog and not a QMainWindow. The MenuBar is gone, the Status Bar is gone.
This commit is contained in:
184
pdfView.py
184
pdfView.py
@@ -1,31 +1,173 @@
|
||||
from PySide6.QtCore import QFile
|
||||
from PySide6.QtPdf import QPdfDocument
|
||||
import math
|
||||
|
||||
from PySide6.QtCore import QFile, QModelIndex, QPoint, Signal, Slot
|
||||
from PySide6.QtPdf import QPdfBookmarkModel, QPdfDocument
|
||||
from PySide6.QtPdfWidgets import QPdfView
|
||||
from PySide6.QtWidgets import QDialog, QVBoxLayout, QWidget
|
||||
from PySide6.QtWidgets import QComboBox, QDialog, QMenuBar, QSpinBox, QWidget
|
||||
from ui.pdfViewer import Ui_pdfViewer
|
||||
|
||||
ZOOM_MULTIPLIER = math.sqrt(2.0)
|
||||
|
||||
class PDFViewer(QDialog):
|
||||
pdf_view: QPdfView
|
||||
pdf_document: QPdfDocument
|
||||
class ZoomSelector(QComboBox):
|
||||
zoom_mode_changed = Signal(QPdfView.ZoomMode)
|
||||
zoom_factor_changed = Signal(float)
|
||||
|
||||
def __init__(self, parent: QWidget|None = None) -> None:
|
||||
super(ZoomSelector, self).__init__(parent)
|
||||
self.setEditable(True)
|
||||
|
||||
def __init__(self, parent: QWidget) -> None:
|
||||
for text in [ 'Fit Width', 'Fit Page', '12%', '25%', '33%', '50%', '66%', '75%', '100%', '125%', '150%', '200%', '400%']:
|
||||
self.addItem(text)
|
||||
self.currentTextChanged.connect(self.on_current_text_changed)
|
||||
lineEdit = self.lineEdit()
|
||||
assert lineEdit is not None
|
||||
lineEdit.editingFinished.connect(self._editing_finished)
|
||||
return
|
||||
@Slot(float) # type: ignore
|
||||
def set_zoom_factor(self, zoomFactor: float) -> None:
|
||||
percent = int(zoomFactor * 100)
|
||||
self.setCurrentText(f"{percent}%")
|
||||
return
|
||||
@Slot()
|
||||
def reset(self) -> None:
|
||||
self.setCurrentIndex(8) # 100%
|
||||
return
|
||||
@Slot(str) # type: ignore
|
||||
def on_current_text_changed(self, text: str) -> None:
|
||||
if text == "Fit Width":
|
||||
self.zoom_mode_changed.emit(QPdfView.ZoomMode.FitToWidth)
|
||||
elif text == "Fit Page":
|
||||
self.zoom_mode_changed.emit(QPdfView.ZoomMode.FitInView)
|
||||
elif text.endswith("%"):
|
||||
zoom_level = int(text[:-1])
|
||||
factor = zoom_level / 100.0
|
||||
self.zoom_mode_changed.emit(QPdfView.ZoomMode.Custom)
|
||||
self.zoom_factor_changed.emit(factor)
|
||||
return
|
||||
@Slot()
|
||||
def _editing_finished(self) -> None:
|
||||
lineEdit = self.lineEdit()
|
||||
assert lineEdit is not None
|
||||
self.on_current_text_changed(lineEdit.text())
|
||||
return
|
||||
|
||||
|
||||
class PDFViewer(QDialog, Ui_pdfViewer):
|
||||
menubar: QMenuBar
|
||||
zoomSelector: ZoomSelector
|
||||
pageSelector: QSpinBox
|
||||
document: QPdfDocument
|
||||
|
||||
def __init__(self, parent: QWidget | None) -> None:
|
||||
super(PDFViewer, self).__init__(parent)
|
||||
self.setupUi(self)
|
||||
|
||||
self.pdf_view = QPdfView()
|
||||
self.pdf_document = QPdfDocument()
|
||||
self.zoomSelector = ZoomSelector(self)
|
||||
self.pageSelector = QSpinBox(self)
|
||||
self.document = QPdfDocument(self)
|
||||
|
||||
layout = QVBoxLayout(self)
|
||||
layout.addWidget(self.pdf_view)
|
||||
self.setLayout(layout)
|
||||
self.zoomSelector.setMaximumWidth(150)
|
||||
self.mainToolBar.insertWidget(self.actionZoom_In, self.zoomSelector)
|
||||
self.mainToolBar.insertWidget(self.actionForward, self.pageSelector)
|
||||
self.pageSelector.valueChanged.connect(self.page_selected)
|
||||
nav = self.pdfView.pageNavigator()
|
||||
nav.currentPageChanged.connect(self.pageSelector.setValue)
|
||||
nav.backAvailableChanged.connect(self.actionBack.setEnabled)
|
||||
nav.forwardAvailableChanged.connect(self.actionForward.setEnabled)
|
||||
self.zoomSelector.zoom_mode_changed.connect(self.pdfView.setZoomMode)
|
||||
self.zoomSelector.zoom_factor_changed.connect(self.pdfView.setZoomFactor)
|
||||
self.zoomSelector.reset()
|
||||
|
||||
bookmark_model = QPdfBookmarkModel(self)
|
||||
bookmark_model.setDocument(self.document)
|
||||
|
||||
self.bookmarkView.setModel(bookmark_model)
|
||||
self.bookmarkView.activated.connect(self.bookmark_selected)
|
||||
|
||||
self.tabWidget.setTabEnabled(1, False) # disable pages tabwidget
|
||||
self.pdfView.setDocument(self.document)
|
||||
self.pdfView.zoomFactorChanged.connect(self.zoomSelector.set_zoom_factor)
|
||||
return
|
||||
|
||||
def load_pdf(self, file: QFile) -> None:
|
||||
if not file.isOpen():
|
||||
file.open(file.OpenModeFlag.ReadOnly)
|
||||
self.pdf_document.load(file)
|
||||
self.pdf_view.setDocument(self.pdf_document)
|
||||
self.pdf_view.setPageMode(QPdfView.PageMode.MultiPage)
|
||||
size = self.pdf_document.pagePointSize(1)
|
||||
self.resize(size.toSize())
|
||||
print(size)
|
||||
@Slot(QFile) # type: ignore
|
||||
def open(self, file: QFile) -> None:
|
||||
#assert file.exists()
|
||||
#if not file.isOpen():
|
||||
#file.open(QFile.OpenModeFlag.ReadOnly)
|
||||
#self.document.load(file)
|
||||
self.document.load(file.fileName())
|
||||
document_title = self.document.metaData(QPdfDocument.MetaDataField.Title)
|
||||
self.setWindowTitle(document_title if document_title else "PDF Viewer")
|
||||
self.page_selected(0)
|
||||
self.pageSelector.setMaximum(self.document.pageCount() -1 )
|
||||
return
|
||||
|
||||
@Slot(QModelIndex) # type: ignore
|
||||
def bookmark_selected(self, index: QModelIndex) -> None:
|
||||
if not index.isValid():
|
||||
return
|
||||
|
||||
page = index.data(int(QPdfBookmarkModel.Role.Page))
|
||||
zoom_level = index.data(int(QPdfBookmarkModel.Role.Level))
|
||||
nav = self.pdfView.pageNavigator()
|
||||
assert nav is not None
|
||||
nav.jump(page, QPoint(), zoom_level)
|
||||
return
|
||||
|
||||
@Slot(int) # type: ignore
|
||||
def page_selected(self, page: int) -> None:
|
||||
nav = self.pdfView.pageNavigator()
|
||||
nav.jump(page, QPoint(), nav.currentZoom())
|
||||
return
|
||||
|
||||
@Slot()
|
||||
def on_actionOpen_triggered(self) -> None:
|
||||
print("What are you doing in actionOpen_triggered?")
|
||||
return
|
||||
|
||||
@Slot()
|
||||
def on_actionQuit_triggered(self) -> None:
|
||||
self.close()
|
||||
return
|
||||
|
||||
@Slot()
|
||||
def on_actionZoom_In_triggered(self) -> None:
|
||||
factor = self.pdfView.zoomFactor() * ZOOM_MULTIPLIER
|
||||
self.pdfView.setZoomFactor(factor)
|
||||
return
|
||||
|
||||
@Slot()
|
||||
def on_actionZoom_Out_triggered(self) -> None:
|
||||
factor = self.pdfView.zoomFactor() / ZOOM_MULTIPLIER
|
||||
self.pdfView.setZoomFactor(factor)
|
||||
return
|
||||
|
||||
@Slot()
|
||||
def on_actionPrevious_Page_triggered(self) -> None:
|
||||
nav = self.pdfView.pageNavigator()
|
||||
nav.jump(nav.currentPage() - 1, QPoint(), nav.currentZoom())
|
||||
return
|
||||
|
||||
@Slot()
|
||||
def on_actionNext_Page_triggered(self) -> None:
|
||||
nav = self.pdfView.pageNavigator()
|
||||
nav.jump(nav.currentPage() + 1, QPoint(), nav.currentZoom())
|
||||
return
|
||||
|
||||
@Slot()
|
||||
def on_actionContinuous_triggered(self) -> None:
|
||||
cont_checked = self.actionContinuous.isChecked()
|
||||
mode = QPdfView.PageMode.MultiPage if cont_checked else QPdfView.PageMode.SinglePage
|
||||
self.pdfView.setPageMode(mode)
|
||||
return
|
||||
|
||||
@Slot()
|
||||
def on_actionBack_triggered(self) -> None:
|
||||
self.pdfView.pageNavigator().back()
|
||||
return
|
||||
|
||||
@Slot()
|
||||
def on_actionForward_triggered(self) -> None:
|
||||
self.pdfView.pageNavigator().forward()
|
||||
return
|
||||
|
||||
|
||||
Reference in New Issue
Block a user