この最初の部分は、本当に必要なものではないことが判明しました。情報提供のために残していますが、下部の更新を参照してください
問題は、QGraphicsView 自体が一種のスクロール ウィジェットであり、表示しているシーンのスライスを表すことです。ビューを単独で使用し、独自のスクロールバーを利用するのが理想的です。
ただし、ビューのコンテンツ サイズを通常の QWidget スクロールに転送する必要がある場合は、シーンのコンテンツが変更されたときに QGraphicsView のサイズを常に変更する必要があります。QScrollArea は、設定されているウィジェットのサイズ変更にのみ応答します。ビューのサイズを変更する必要があります。プロセスは、ビューが追加または削除されたアイテムのシーンからの信号をリッスンし、それらのすべての子を完全に囲むようにサイズを変更する必要があるというものです。
以下は、QGraphicsView ウィジェットが単独でスクロール機能として完全に機能する方法の例です。
from PyQt4 import QtCore, QtGui
app = QtGui.QApplication([])
scene = QtGui.QGraphicsScene()
view = QtGui.QGraphicsView()
view.setScene(scene)
view.resize(600,300)
pix = QtGui.QPixmap("image.png")
w,h = pix.width(), pix.height()
x = y = 0
pad = 5
col = 3
for i in xrange(1,20):
item = scene.addPixmap(pix)
item.setPos(x,y)
if i % col == 0:
x = 0
y += h+pad
else:
x+=w+pad
view.show()
view.raise_()
app.exec_()
画像がビューの現在のサイズを超えると、スクロールバーが表示されることがわかります。
ビューのスクロールとして機能する親スクロール領域が本当に必要な場合 (理由はよくわかりません)、シーンで何らかのイベントを監視し、常に監視する必要がある方法を示すより複雑な例を次に示します。ビューのサイズを更新して、親スクロール領域にスクロールバーを強制します。rect が変更されたとき (子が追加されたとき) に、シーンでシグナルを監視することを選択しました。
from PyQt4 import QtCore, QtGui
app = QtGui.QApplication([])
win = QtGui.QDialog()
win.resize(600,300)
layout = QtGui.QVBoxLayout(win)
scroll = QtGui.QScrollArea()
scroll.setWidgetResizable(True)
layout.addWidget(scroll)
view = QtGui.QGraphicsView(scroll)
view.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
view.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
scene = QtGui.QGraphicsScene(scroll)
view.setScene(scene)
scroll.setWidget(view)
pix = QtGui.QPixmap("image.png")
w,h = pix.width(), pix.height()
x = y = i = 0
pad = 5
col = 3
def createImage():
global x,y,i
item = scene.addPixmap(pix)
item.setPos(x,y)
i+=1
if i % col == 0:
x = 0
y += h+pad
else:
x+=w+pad
def changed():
size = scene.itemsBoundingRect().size()
view.setMinimumSize(size.width()+pad, size.height()+pad)
scene.changed.connect(changed)
t = QtCore.QTimer(win)
t.timeout.connect(createImage)
t.start(500)
win.show()
win.raise_()
app.exec_()
スクロール領域は、子として設定されているウィジェットのサイズを常に見ています。ビューのサイズを変更する必要があります。
アップデート
コメントからわかるように、このアプローチでは QGraphics オブジェクトを実際に使用する必要はありませんでした。それはあなたの仕事をより複雑にするだけでした。垂直レイアウトを使用して、QLabel ウィジェットを追加するだけです。
from PyQt4 import QtCore, QtGui
app = QtGui.QApplication([])
win = QtGui.QDialog()
win.resize(300,300)
layout = QtGui.QVBoxLayout(win)
scroll = QtGui.QScrollArea()
scroll.setWidgetResizable(True)
layout.addWidget(scroll)
scrollContents = QtGui.QWidget()
layout = QtGui.QVBoxLayout(scrollContents)
scroll.setWidget(scrollContents)
pix = QtGui.QPixmap("image.png")
def createImage():
label = QtGui.QLabel()
label.setPixmap(pix)
layout.addWidget(label)
t = QtCore.QTimer(win)
t.timeout.connect(createImage)
t.start(500)
win.show()
win.raise_()
app.exec_()