How to make a widget's height a fixed proportion to its width
<p>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 height should be a fixed proportion. In other words, the banner image's height should depend on the width of the window. The widget beneath the banner (the main content) should stretch to fill all available vertical space.</p>

<p>I've basically ported <a href="https://stackoverflow.com/a/14107727/1450294">this SO answer</a> to PyQt5:</p>

<pre><code>class Banner(QWidget):

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

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

        pixmap = QPixmap('banner-1071797_960_720.jpg') # see note below

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

        self._resizeImage()

    def resizeEvent(self, event):
        super(Banner, self).resizeEvent(event)
        self._resizeImage()

    def _resizeImage(self):
        pixSize = self._label.pixmap().size()
        pixSize.scale(self.size(), Qt.KeepAspectRatio)
        self._label.setFixedSize(pixSize)
</code></pre>

<p>(For this example, I'm using <a href="https://pixabay.com/en/banner-header-wave-line-swing-1071797/" rel="nofollow noreferrer">this</a> free banner image, but there's nothing special about it.)</p>

<p>I've put the banner in the application code below, where a label serves as a placeholder for the main content:</p>

<pre><code>if __name__ == '__main__':

    app = QApplication(sys.argv)

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

    banner = Banner(widget)
    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(0, 1)

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

    sys.exit(app.exec_())
</code></pre>

<p>The problem is, the label fills 100% of the window—the banner isn't visible at all.</p>

<p>I've tried many different size policies and stretch factors, and removing size policies altogether, but haven't found how to do what I need. The image in the banner should be proportionately scaled to fit the window's width, and the label should fill the remaining vertical space in the window.</p>

<p>Ideas?</p>