3

私はPyQt4とpython-popplerqt4を使用してPDFリーダーに取り組んでいます。PDFページ(QPixmaps)はQLablesに表示され、QFrameに垂直に配置されます。QFrameはQScrollAreaに配置されます。

QMainWindow
   |_ QScrollArea
        |_ QFrame (Document: stretch)
            |_ QLabel (Page: fixed size)
            |   |_ QPixmap (stretch)
            |_ QLabel
            |   |_ QPixmap
            |_ etc.

ドキュメントのサイズは、QLabelの固定サイズによって決まります。QPixmapはそれに応じて拡大するように設定されており、ページ周辺のQFrameは自然にそのサイズを調整します。

ズームを呼び出すと、ページ(QLabels)のサイズが1つずつ変更されQLabel.setFixedSize()ます。ただし、その効果は期待外れです。ドキュメントのサイズを変更すると、ぎこちなくちらつきます。EvinceまたはMendeleyのズームインは、比較すると非常にスムーズです。

QFrame.hide()スケーリングの前と後の呼び出しがQFrame.show()役立つことを他の場所で読んだことがあります。確かにそれは小さな文書のために行います。ただし、たとえば約700ページのPDFに適用すると、1秒以上空白のQScrollAreaを意味します。良くない。

QScrollAreaでドキュメントを拡大縮小して、スムーズなズーム効果を生成するにはどうすればよいですか?

PS: Poppler.Pagesの画像は、表示されているQLabel受信者に対してのみ描画されます。つまり、700ページのドキュメントのサイズ変更には、多くの画像のサイズ変更は含まれません。実際には、最大で2〜4枚の画像のサイズが変更されます(解像度が高くなるほど、解像度は低くなります)。Documentオブジェクトのサイズ変更は、ほとんどの場合空のQLabelのサイズ変更のみで構成されます。

4

1 に答える 1

4

いくつかの調査と QtForums からのいくつかの助けの後、 QScrollArea で目的のズーム効果を実現するための簡単な解決策はないようです。そうでなければ私が間違っていることを証明してください。

実装は簡単ではありませんが、より優れたツールはQGraphicsView. QGraphicsView.scale(float, float)ズームを完璧に行う方法があります!また、このスケール方法ではコンテンツを維持する必要さえないため、使用するのもはるかに簡単です (最初から高解像度をロードしない場合の画像の解像度を除く)。

QGraphicsSceneただし、QGraphicsView のコンテンツは少し怠け者であり、特にレイアウトに関しては、セットアップにさらに作業が必要です。私の場合、私は PDF ビューアで作業しているので、画像を縦に並べる必要QGraphicsLinearLayoutがあります。

後世のために、ピックスマップをレイアウト、シーン、ビューに実装する方法を示すコード例を次に示します。もちろん、コンテンツをスケーリングする方法も示しています。

#!/usr/bin/env python

import sys
from PyQt4 import QtGui, QtCore
from popplerqt4 import Poppler

class Application(QtGui.QApplication):

    def __init__(self):
        QtGui.QApplication.__init__(self, sys.argv)

        scene = QtGui.QGraphicsScene()
        scene.setBackgroundBrush(QtGui.QColor('darkGray'))
        layout = QtGui.QGraphicsLinearLayout(QtCore.Qt.Vertical)
        document = Poppler.Document.load('/home/test.pdf')
        document.setRenderHint(Poppler.Document.Antialiasing)
        document.setRenderHint(Poppler.Document.TextAntialiasing)
        for number in range(document.numPages()):
            page = document.page(number)
            image = page.renderToImage(100, 100)
            pixmap = QtGui.QPixmap.fromImage(image)
            container = QtGui.QLabel()
            container.setFixedSize(page.pageSize())
            container.setStyleSheet("Page { background-color : white}")
            container.setContentsMargins(0, 0, 0, 0)
            container.setScaledContents(True)
            container.setPixmap(pixmap)
            label = scene.addWidget(container)
            layout.addItem(label)

        graphicsWidget = QtGui.QGraphicsWidget()
        graphicsWidget.setLayout(layout)
        scene.addItem(graphicsWidget)
        self.view = View(scene)
        self.view.show()


class View(QtGui.QGraphicsView):

    def __init__(self, parent = None):
        QtGui.QGraphicsView.__init__(self, parent)

    def wheelEvent(self, event):

        if event.delta() > 0:
            self.scale(1.1, 1.1)
        else:
            self.scale(0.9, 0.9)

if __name__ == "__main__":
        application = Application()
        sys.exit(application.exec_())
于 2012-05-25T17:58:17.457 に答える