PySide6结合PyMuPDF显示PDF时窗口缩放出现剪切失真问题
PySide结合PyMuPDF查看PDF窗口缩放时剪切失真的解决方法
问题描述
使用PySide6结合PyMuPDF开发PDF查看器时,调整窗口大小会出现PDF内容剪切、失真的问题。
问题原因
- 直接将
resizeEvent赋值给render_page,未调用父类的resizeEvent方法,导致窗口布局逻辑异常。 - 计算缩放比例时使用主窗口尺寸,而非滚动区域的视口可用空间,渲染的PDF尺寸与显示区域不匹配。
- 滚动区域开启
WidgetResizable=True后,标签控件尺寸随滚动区域变化,进一步干扰渲染尺寸计算。
修复后的代码
import sys import fitz from PySide6.QtWidgets import QApplication, QLabel, QMainWindow, QScrollArea from PySide6.QtGui import QPixmap, QImage from PySide6.QtCore import Qt class PDFWindow(QMainWindow): def __init__(self, filename): super().__init__() # 打开PDF并获取第一页 self.pdf_doc = fitz.open(filename) self.page = self.pdf_doc[0] # 创建用于显示PDF页面的QLabel self.label = QLabel() self.label.setAlignment(Qt.AlignCenter) # 禁止标签自动调整大小,避免干扰渲染尺寸 self.label.setSizePolicy(Qt.Ignored, Qt.Ignored) # 创建滚动区域 self.scroll_area = QScrollArea() self.scroll_area.setWidget(self.label) # 关闭WidgetResizable,手动控制标签尺寸 self.scroll_area.setWidgetResizable(False) self.setCentralWidget(self.scroll_area) # 初始渲染页面 self.render_page() def resizeEvent(self, event): # 调用父类的resizeEvent确保窗口正常布局 super().resizeEvent(event) self.render_page() def render_page(self): # 获取滚动区域视口的可用尺寸 viewport_size = self.scroll_area.viewport().size() page_rect = self.page.rect() page_width = page_rect.width page_height = page_rect.height # 计算保持宽高比的缩放比例 zoom_width = viewport_size.width() / page_width zoom_height = viewport_size.height() / page_height zoom = min(zoom_width, zoom_height) # 确保缩放比例不小于0.1,避免过小 zoom = max(zoom, 0.1) # 渲染PDF页面为Pixmap pixmap = self.page.get_pixmap(matrix=fitz.Matrix(zoom, zoom), colorspace='rgb') image = QImage(pixmap.samples, pixmap.width, pixmap.height, QImage.Format_RGB888) cur_pixmap = QPixmap.fromImage(image) # 更新标签的Pixmap和尺寸 self.label.setPixmap(cur_pixmap) self.label.resize(cur_pixmap.size()) if __name__ == "__main__": app = QApplication(sys.argv) window = PDFWindow("example.pdf") window.show() sys.exit(app.exec())
关键修改点
- 重写resizeEvent:不再直接赋值,而是重写方法并调用父类实现,保证窗口布局逻辑正常执行。
- 使用视口尺寸计算缩放:用滚动区域的
viewport().size()替代主窗口大小,确保基于实际显示区域计算缩放比例。 - 关闭WidgetResizable:手动控制标签的尺寸,避免滚动区域自动调整标签大小导致的渲染偏差。
- 保持宽高比:通过取宽高缩放比例的最小值,确保PDF页面完整显示且不变形。
- 设置标签尺寸策略:将标签的尺寸策略设为
Ignored,避免Qt自动调整标签大小影响渲染结果。
内容的提问来源于stack exchange,提问作者Matt Harrison
相关产品推荐
相关产品推荐

