Skip to content Skip to sidebar Skip to footer

How To Make A Widget's Height A Fixed Proportion To Its Width

I'm working on a PyQt5 application that needs to have a banner along the top. The banner is just a wide image, whose width should always be the width of the window, and whose heigh

Solution 1:

@kuba-ober's comment was right: I had to implement hasHeightForWidth() and heightForWidth() in the Banner class.

Here's the modified code, which works the way I want. All the modifications have comments within the code.

classBanner(QWidget):

    def__init__(self, parent):
        super(Banner, self).__init__(parent)

        self.setContentsMargins(0, 0, 0, 0)

        pixmap = QPixmap('banner-1071797_960_720.jpg')

        # First, we note the correct proportion for the pixmap
        pixmapSize = pixmap.size()
        self._heightForWidthFactor = 1.0 * pixmapSize.height() / pixmapSize.width()

        self._label = QLabel('pixmap', self)
        self._label.setPixmap(pixmap)
        self._label.setScaledContents(True)
        self._label.setFixedSize(0, 0)
        self._label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

        self._resizeImage(self.size())

    defhasHeightForWidth(self):
        # This tells the layout manager that the banner's height does depend on its widthreturnTruedefheightForWidth(self, width):
        # This tells the layout manager what the preferred and minimum height are, for a given widthreturn math.ceil(width * self._heightForWidthFactor)

    defresizeEvent(self, event):
        super(Banner, self).resizeEvent(event)
        # For efficiency, we pass the size from the event to _resizeImage()
        self._resizeImage(event.size())

    def_resizeImage(self, size):
        # Since we're keeping _heightForWidthFactor, we can code a more efficient implementation of this, too
        width = size.width()
        height = self.heightForWidth(width)
        self._label.setFixedSize(width, height)

if __name__ == '__main__':

    app = QApplication(sys.argv)

    widget = QWidget()
    widget.setContentsMargins(0, 0, 0, 0)
    layout = QVBoxLayout(widget)

    banner = Banner(widget)
    # Turns out we don't need the bannerSizePolicy now#   bannerSizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)#   bannerSizePolicy.setHeightForWidth(True)#   banner.setSizePolicy(bannerSizePolicy)
    layout.addWidget(banner)

    label = QLabel('There should be a banner above')
    label.setStyleSheet("QLabel { background-color: grey; color: white; }");
    layout.addWidget(label)
    layout.setStretch(1, 1)

    widget.resize(320, 200)
    widget.move(320, 200)
    widget.setWindowTitle('Banner Tester')
    widget.show()

    sys.exit(app.exec_())

Post a Comment for "How To Make A Widget's Height A Fixed Proportion To Its Width"