QScrollArea 不会确认设置小部件的大小
QScrollArea won't acknowledge set widget's size
我正在尝试实现类似 pinterest 的 UI,并且我一直在尝试 PySide 的 FlowLayout 示例。
问题是我正在尝试使用 QScrollArea,但它无法让我充分向下滚动。换句话说,我无法到达要滚动的小部件的底部。
您可以获得孔文件here。如果您下载它并 运行 它,问题将变得非常明显。
我的代码取自 here,并进行了以下修改:
添加了这个class:(它只是让我生成彩色和数字矩形)
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_())
提前致谢!
好吧,我自己找到了答案...
显然,布局必须定义方法 heightForWidth
,据我所知,return 是调整宽度后产生的布局高度。所以...我不得不在 doLayout
的末尾存储新的高度,这样我就可以在需要时 return 它。
这是我在doLayout
之后所做的:
self.heightForWidthValue = max(map(lambda position : position.y(), availablePositions))
此外,我在FlowLayout
中实现了这些功能:
def hasHeightForWidth(self):
return True
def heightForWidth(self, width):
return self.heightForWidthValue
并将0
设置为heightForWidthValue
的默认值(在FlowLayout->__init__
中初始化)。
现在它就像一个魅力:)
Here 的正确代码,如果有人感兴趣的话。
我正在尝试实现类似 pinterest 的 UI,并且我一直在尝试 PySide 的 FlowLayout 示例。
问题是我正在尝试使用 QScrollArea,但它无法让我充分向下滚动。换句话说,我无法到达要滚动的小部件的底部。
您可以获得孔文件here。如果您下载它并 运行 它,问题将变得非常明显。
我的代码取自 here,并进行了以下修改:
添加了这个class:(它只是让我生成彩色和数字矩形)
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_())
提前致谢!
好吧,我自己找到了答案...
显然,布局必须定义方法 heightForWidth
,据我所知,return 是调整宽度后产生的布局高度。所以...我不得不在 doLayout
的末尾存储新的高度,这样我就可以在需要时 return 它。
这是我在doLayout
之后所做的:
self.heightForWidthValue = max(map(lambda position : position.y(), availablePositions))
此外,我在FlowLayout
中实现了这些功能:
def hasHeightForWidth(self):
return True
def heightForWidth(self, width):
return self.heightForWidthValue
并将0
设置为heightForWidthValue
的默认值(在FlowLayout->__init__
中初始化)。
现在它就像一个魅力:)
Here 的正确代码,如果有人感兴趣的话。