I am trying to create QScrollArea with QHBoxLayout inside containing a row od QWidgets. I want the widgets to occupy all available height and adjust it's size accordingly.
My widgets are QLabels displaying scaled-to-size QPixmaps inside. In my project those are photos. I implemented heightForWidth and sizeHint methods to achieve good scaling. Still I'm unable to achieve correct height.
By default widgets are scaled so that scrollarea does not need scrollbars.
No scrollbars needed
I played with sizePolicy of the scroll widget but was only able to force widgets to have its size equal to its maximum size returned from sizeHint. Horizontal scroll is active then.
Maximum size of widgets exceeds window height
When I change sizeHint to return QSize(width(), heightForWidth(width())) I observe that width() returns up to 640 pixels and never more. I could not figure out where this limit of 640 comes from.
Is there a way to remove the 640px width limit in my layout or is there any way to force widgets to scale up to window height?
class ImageWidget(QLabel):
PIXMAP_SIZE = QSize(1000, 500)
def __init__(self, parent=None):
super(ImageWidget, self).__init__(parent)
self._imagePixmap = QtGui.QPixmap(self.PIXMAP_SIZE)
self._imagePixmap.fill(QtGui.QColor(Qt.green))
self.setScaledContents(False)
self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
self.setStyleSheet("border:1px solid red;")
def paintEvent(self, event):
size = self.size()
point = QPoint(0, 0)
scaledPix = self._imagePixmap.scaled(size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
point.setX((size.width() - scaledPix.width())/2)
point.setY((size.height() - scaledPix.height())/2)
QtGui.QPainter(self).drawPixmap(point, scaledPix)
def heightForWidth(self, width):
return self._imagePixmap.height() * width / self._imagePixmap.width() if self._imagePixmap.width() else 0
def hasHeightForWidth(self):
return self._imagePixmap is not None
def sizeHint(self):
return QSize(self.width(), self.heightForWidth(self.width()))
# self.width() has max value of 640 !
#return self.PIXMAP_SIZE
class App(QMainWindow):
def __init__(self):
super(App, self).__init__()
self.seriesLayout = QHBoxLayout()
scrollWidget = QWidget()
scrollWidget.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Maximum)
scrollWidget.setLayout(self.seriesLayout)
scroll = QScrollArea()
scroll.setWidgetResizable(True)
scroll.setWidget(scrollWidget)
self.setCentralWidget(scroll)
for col in range(5):
self.seriesLayout.addWidget(ImageWidget())
QScrollArea
doesn't do any of it. You must resize the widget yourself, otherwise none of your expectations can even begin to be upheld. – Kuba hasn't forgotten Monica