第一部分结果不是你真正需要的。我将其保留以供参考,但请参阅底部的更新
问题是 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_()
您可以看到,当图像超出视图的当前大小时,您会看到滚动条。
如果您确实需要一些父滚动区域作为视图的滚动(出于我不太了解的原因),那么这里有一个更复杂的示例,显示您需要如何监视场景中的某些事件,然后不断更新视图的大小以在父滚动区域上强制滚动条。我选择在场景中观看信号,以了解其矩形何时发生变化(添加了更多孩子)
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_()