|
|
from PyQt5.QtWidgets import QScrollArea, QLabel, QVBoxLayout, QWidget, QSizePolicy from PyQt5.QtCore import Qt, QPoint, QSize from PyQt5.QtGui import QPixmap, QImage, QResizeEvent, QPainter
import fitz
class PDFLabel(QLabel): def __init__(self, parent): super().__init__(parent) self.parent = parent self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred) def paintEvent(self, event): self.adjustSize() if self.pixmap() is not None: painter = QPainter(self) # painter.setRenderHint(QPainter.Antialiasing) parentLayoutMargins = self.parent.scrollAreaLayout.getContentsMargins() parentMargins = self.parent.getContentsMargins() if self.parent.verticalScrollBar().isVisible(): scrollBarWidth = self.parent.verticalScrollBar().sizeHint().width() else: scrollBarWidth = 0 totalMargin = parentLayoutMargins[0] + parentLayoutMargins[2] + \ parentMargins[0]*2 + scrollBarWidth idealWidth = self.parent.width() - totalMargin # print(idealWidth) pixSize = self.pixmap().size() # print(pixSize) # print((self.parent.scrollAreaContents.size())) pixSize.scale(idealWidth, 1000000, Qt.KeepAspectRatio) scaledPix = self.pixmap().scaled(pixSize, Qt.KeepAspectRatio, Qt.SmoothTransformation) painter.drawPixmap(QPoint(), scaledPix) self.setMaximumSize(pixSize)
class PDFViewer(QScrollArea): def __init__(self, parent): super().__init__(parent) self.scrollAreaContents = QWidget() self.scrollAreaLayout = QVBoxLayout()
self.setWidget(self.scrollAreaContents) self.setWidgetResizable(True) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # set a fixed background colour # on some OSes (Mac, Haiku) it is grey automatically but not on KDE self.setStyleSheet('PDFViewer {background-color: #D8D8D8}')
self.scrollAreaContents.setLayout(self.scrollAreaLayout) self.pixmapList = [] self.lastVScrollPosition = None def update_pdf(self, pdf): self.render(pdf) self.clear() self.show()
def render(self, pdf): """
Update the preview shown by rendering a new PDF and drawing it to the scroll area. """
self.pixmapList = [] pdfView = fitz.Document(stream=pdf, filetype='pdf') for page in pdfView: # needs to be high enough for big monitors. 300 should do it... self.pixmapList.append(page.get_pixmap(dpi=300, alpha=False)) def clear(self): self.lastVScrollPosition = self.verticalScrollBar().value() while self.scrollAreaLayout.count(): item = self.scrollAreaLayout.takeAt(0) w = item.widget() if w: w.deleteLater() def show(self): for p in self.pixmapList: label = PDFLabel(parent=self) label.setAlignment(Qt.AlignHCenter) qtimg = QImage(p.samples, p.width, p.height, p.stride, QImage.Format_RGB888) label.setPixmap(QPixmap.fromImage(qtimg)) self.scrollAreaLayout.addWidget(label) self.scrollAreaLayout.addStretch(1) # Somewhat of a hack. Should really replace pixmaps in place # rather than removing labels elsewhere in code. if self.lastVScrollPosition: self.verticalScrollBar().setValue(self.lastVScrollPosition)
|