我正在尝试使用PyQt4和python-poppler-qt4制作一个显示PDF文件的应用程序。
到目前为止,我已经设法通过加载使用Poppler生成的像素图来显示整个文档,该像素图设置在QLabel上并附加到QFrame。QFrame 显示在 QScrollArea 中。
它看起来相当不错,直到实现缩放,这是通过重新生成像素图来完成的,分辨率增加。此过程需要将整个文档呈现为像素图,这显然需要时间并导致不必要的滞后。
逻辑希望我只显示我看到的页面的图像(听起来像量子物理学(。我想到两个选择:
- 使用 QLabels创建空白页,并在滚动区域中可见时将图像加载到空白页上;
- 仅创建一个页面,并在应显示之前添加或删除先例或后续页面。
不确定我是否走在正确的轨道上,或者是否有其他选择。
第一个选项似乎更可行,因为空白页面的可见性决定了何时必须上传像素图(尽管我不知道在页面隐藏时如何删除该像素图(。然而,我不确定这种方式的缩放速度会更快,因为必须重新生成一个 600 页的文档,尽管是空白页。
第二个选项绝对应该改善缩放,因为在缩放时必须一次重新生成 1 到 4 页。但是,在第二种情况下,我不确定如何触发页面的构造。
你有什么建议?
QLabel
s并直接绘制图像不是很简单吗:
from PyQt4.QtGui import *
import sys
app = QApplication(sys.argv)
class Test(QWidget):
def __init__(self):
super(Test, self).__init__()
self.painter = QPainter()
# placeholder for the real stuff to draw
self.image = QImage("/tmp/test.jpg")
def paintEvent(self, evt):
rect = evt.rect()
evt.accept()
print rect
self.painter.begin(self)
zoomedImage = self.image # ... calculate this for your images
sourceRect = rect # ... caluclate this ...
# draw it directly
self.painter.drawImage(rect, self.image, sourceRect)
self.painter.end()
t = Test()
t.setGeometry(0,0,600,800)
s = QScrollArea()
s.setWidget(t)
s.setGeometry(0,0,300,400)
s.show()
app.exec_()
我已经使用问题中的选项 1 得出了一个答案:
def moveEvent(self, event):
self.checkVisibility()
event.ignore()
def resizeEvent(self, event):
self.checkVisibility()
event.ignore()
def checkVisibility(self):
print "Checking visibility"
for page in self.getPages():
if not page.visibleRegion().isEmpty():
if page.was_visible:
pass
else:
print page.page_number, "became visible"
page.was_visible = True
self.applyImageToPage(page)
else:
if page.was_visible:
print page.page_number, "became invisible"
page.was_visible = False
else:
pass
def applyImageToPage(self, page):
print "applying image to page", page.page_number
source = self.getSourcePage(self.getPageNumber(page))
scale = self.display.scale
# this is where the error occurs
image = source.renderToImage(72 * scale, 72 * scale)
pixmap = QtGui.QPixmap.fromImage(image)
page.setPixmap(pixmap)