QScrollArea不会确认设置小部件的大小

时间:2015-09-24 03:03:42

标签: qt pyqt pyside

我试图实现类似pinterest的UI,我一直在试验PySide的FlowLayout示例。

问题是我尝试使用QScrollArea并且它不会让我向下滚动。换句话说,我无法触及小部件的底部,我试图滚动。

您可以获取孔文件here。如果你下载并运行它,问题将变得非常明显。

我的代码取自here,并进行了以下修改:

添加了这个类:(它只是让我生成彩色和数字矩形)

class ColoredRectangle(QLabel):
count = 0

def __init__(self, height, color):
    super(ColoredRectangle, self).__init__()

    palette = QPalette()
    palette.setColor(QPalette.Background, color)

    self.setAutoFillBackground(True)
    self.setPalette(palette)

    self.setFixedSize(200, height)
    self.setText(str(ColoredRectangle.count))
    ColoredRectangle.count += 1

现在我添加了矩形而不是按钮......

class Window(QtGui.QWidget):
def __init__(self):
    super(Window, self).__init__()

    flowLayout = FlowLayout()
    flowLayout.addWidget(ColoredRectangle(450, Qt.white))
    flowLayout.addWidget(ColoredRectangle(200, Qt.green))self.setLayout(flowLayout)

    self.setLayout(flowLayout)

    self.setWindowTitle("Flow Layout")

更改了doLayout方法,如下所示:

def doLayout(self, rect):

    if not any(self.itemList):
        return

    firstItem = self.itemList[0]

    x = rect.x()
    y = rect.y()

    wid = firstItem.widget()

    spaceX = self.spacing() + wid.style().layoutSpacing(QtGui.QSizePolicy.PushButton,
                                                            QtGui.QSizePolicy.PushButton, QtCore.Qt.Horizontal)
    spaceY = self.spacing() + wid.style().layoutSpacing(QtGui.QSizePolicy.PushButton,
                                                            QtGui.QSizePolicy.PushButton, QtCore.Qt.Vertical)

    itemWidth = firstItem.sizeHint().width()

    # calculate column count

    columnCount = (rect.width() + spaceX) / (itemWidth + spaceX)
    availablePositions = [None] * columnCount

    for i in range(columnCount):
        availablePositions[i] = QPoint(x + i * (itemWidth + spaceX), y)

    for item in self.itemList:

        currentPosition = availablePositions[0]
        currentPositionColumn = 0

        positionColumn = 0
        for position in availablePositions:
            if min(currentPosition.y(), position.y()) != currentPosition.y():
                currentPositionColumn = positionColumn
                currentPosition = position

            positionColumn += 1

        # update available position in column
        itemSize = item.sizeHint()
        availablePositions[currentPositionColumn] = QPoint(currentPosition.x(),
                                                           currentPosition.y() + itemSize.height() + spaceY)

        # place item
        item.setGeometry(QtCore.QRect(currentPosition, itemSize))

最后,我添加了QScrollArea:

if __name__ == '__main__':
import sys

app = QtGui.QApplication(sys.argv)
mainWin = Window()
scrollArea = QScrollArea()
scrollArea.setWidgetResizable(True)
scrollArea.setWidget(mainWin)
scrollArea.show()
sys.exit(app.exec_())

提前致谢!

1 个答案:

答案 0 :(得分:1)

好吧,我自己找到了答案...... 显然,布局必须定义方法heightForWidth,据我所知,它返回宽度调整后的布局高度。所以...我必须在doLayout的末尾存储新的高度,所以我可以在被要求时返回它。 这是我在doLayout之后做的: self.heightForWidthValue = max(map(lambda position:position.y(),availablePositions)) 另外,我在FlowLayout中实现了这些功能: def hasHeightForWidth(self):     返回True def heightForWidth(self,width):     返回self.heightForWidthValue 并为heightForWidthValue设置0作为默认值(在FlowLayout-> __ init__中初始化)。 现在它就像一个魅力:) 如果有人有兴趣,这是正确的代码。