Python 3.x 使用python和PyQt创建可滚动列表

Python 3.x 使用python和PyQt创建可滚动列表,python-3.x,pyqt4,Python 3.x,Pyqt4,我的应用程序中有一个qscrollara,里面有一个QWidget(content_widget)。我想在应用程序运行时用图像填充它。我想有滚动的行为,如果图像的数量超过了数字,可以不滚动显示。我走了这么远: children_occupied_width = self.ui.content_widget.childrenRect().width() image_view = QtGui.QGraphicsView(self.ui.content_widget) image_view.setG

我的应用程序中有一个qscrollara,里面有一个QWidget(content_widget)。我想在应用程序运行时用图像填充它。我想有滚动的行为,如果图像的数量超过了数字,可以不滚动显示。我走了这么远:

children_occupied_width = self.ui.content_widget.childrenRect().width()

image_view = QtGui.QGraphicsView(self.ui.content_widget)
image_view.setGeometry(QtCore.QRect( children_occupied_width, 0, 210, 210 ))
image_view.setObjectName("New Image")

placeholder_image = QtGui.QGraphicsScene()
placeholder_image.addPixmap(QtGui.QPixmap('placeholder.png'))
image_view.setScene(placeholder_image)

image_view.show()
虽然图像显示在列表中的正确位置,但如果图像开始放置在可见区域之外,则不会滚动。内容小部件的大小似乎不会随着时间的推移而改变

self.ui.content_widget.resize(...)

如何使其增长/调整大小?

第一部分原来不是您真正需要的。我把它留作参考之用,但请参见底部的更新

问题在于QGraphicsView本身就是一种滚动小部件,表示它正在查看的场景的一部分。理想情况下,您只需使用视图本身,并使用它自己的滚动条

但是,如果您特别需要将视图的内容大小转发到正常的QWidget滚动,那么您需要做的是使QGraphicsView在场景内容更改时始终调整自身大小。QScrollArea只会对其设置的小部件的大小变化做出响应。视图需要更改大小。这个过程是,视图需要监听场景中添加或删除项目的信号,然后调整自身大小以完全包围所有这些子项

以下是QGraphicsView小部件本身如何完美地充当滚动功能的示例:

从PyQt4导入QtCore,QtGui
app=QtGui.QApplication([])
scene=QtGui.qgraphicscene()
view=QtGui.QGraphicsView()
view.setScene(场景)
视图。调整大小(600300)
pix=QtGui.QPixmap(“image.png”)
w、 h=pix.width(),pix.height()
x=y=0
pad=5
col=3
对于x范围内的i(1,20):
item=scene.addPixmap(pix)
项目.设置位置(x,y)
如果i%col==0:
x=0
y+=h+焊盘
其他:
x+=w+焊盘
view.show()
view.raise_uuz()
app.exec()
您可以看到,当图像溢出视图的当前大小时,会出现滚动条。
如果您真的需要某个父滚动区域作为视图的滚动(原因我不太明白),那么下面是一个更复杂的示例,说明您需要如何在场景中观察某些事件,然后不断更新视图的大小,以强制父滚动区域上的滚动条。我选择在场景中观察信号的rect变化(添加更多子对象)

从PyQt4导入QtCore,QtGui
app=QtGui.QApplication([])
win=QtGui.QDialog()
win.resize(600300)
layout=QtGui.QVBoxLayout(win)
scroll=QtGui.QScrollArea()
scroll.setWidgetResizeable(True)
layout.addWidget(滚动)
视图=QtGui.QGraphicsView(滚动)
view.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
view.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
场景=QtGui.qgraphicscene(滚动)
view.setScene(场景)
scroll.setWidget(视图)
pix=QtGui.QPixmap(“image.png”)
w、 h=pix.width(),pix.height()
x=y=i=0
pad=5
col=3
def createImage():
全局x,y,i
item=scene.addPixmap(pix)
项目.设置位置(x,y)
i+=1
如果i%col==0:
x=0
y+=h+焊盘
其他:
x+=w+焊盘
def changed():
size=scene.itemsBoundingRect().size()
view.setMinimumSize(size.width()+焊盘,size.height()+焊盘)
场景。更改。连接(更改)
t=QtCore.QTimer(win)
t、 超时。连接(createImage)
t、 开始(500)
win.show()
赢,养()
app.exec()
滚动区域始终查看已设置为子级的小部件的大小。必须调整视图的大小

更新

从您的评论中可以看出,这种方法实际上不需要使用QGraphics对象。这只会让你的任务更复杂。只需使用垂直布局并向其中添加QLabel小部件:

从PyQt4导入QtCore,QtGui
app=QtGui.QApplication([])
win=QtGui.QDialog()
win.resize(300300)
layout=QtGui.QVBoxLayout(win)
scroll=QtGui.QScrollArea()
scroll.setWidgetResizeable(True)
layout.addWidget(滚动)
scrollContents=QtGui.QWidget()
layout=QtGui.QVBoxLayout(滚动内容)
scroll.setWidget(scrollContents)
pix=QtGui.QPixmap(“image.png”)
def createImage():
label=QtGui.QLabel()
label.setPixmap(pix)
layout.addWidget(标签)
t=QtCore.QTimer(win)
t、 超时。连接(createImage)
t、 开始(500)
win.show()
赢,养()
app.exec()

我至少找到了
resize
在我的代码中不起作用的原因。将QScroll区域的
widgetsizeable
属性设置为false(或在Qt设计器中禁用它)使其工作。

QGraphicsView对其正在查看的场景具有自己的滚动功能。你为什么不使用它?我知道,但我试着展示一组图像,而不是一个大的图像。场景中到底是什么并不重要。1图像。100张图片。从技术上讲,您可以只使用图形视图上的滚动条。禁用它们需要更多的工作,并且必须将大小与另一个小部件关联起来。好的,将所有图像放在一个QGraphicsView中的方法是我从未想过的。您以前是如何安排它们的?是的,这正是问题所在。但是如何改变小部件的大小呢?我的例子展示了如何通过信号连接不断调整QGraphicsView的大小,直到场景发生变化。也许有一天我可以使用它。我完全被你对QGraphics的使用所抛弃。我没有意识到你真正需要的只是一个包含一堆QLabel的垂直布局
self.ui.content_widget.adjustSize()