Search code examples
pythonqtpyqtpyqt5

setSizePolicy() with QSizePolicy.Expanding does not work: the child does not expand to the size of the parent


According to http://doc.qt.io/qt-5/qsizepolicy.html#Policy-enum, setting the size policy of a widget has the following effect:

The sizeHint() is a sensible size, but the widget can be shrunk and still be useful. The widget can make use of extra space, so it should get as much space as possible (e.g. the horizontal direction of a horizontal slider).

So, I expect the Yellow widget below to fill up the Green widget, but that does not happen. What did I do wrong?

enter image description here

import sys

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

class Yellow(QWidget):

    def __init__(self, *args):
        super().__init__(*args)

        # Set palette
        bg = QPalette()
        bg.setColor(QPalette.Window, Qt.yellow)
        self.setAutoFillBackground(True)
        self.setPalette(bg)

        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

class Green(QWidget):

    def __init__(self, *args):
        super().__init__(*args)

        # Set palette
        bg = QPalette()
        bg.setColor(QPalette.Window, Qt.green)
        self.setAutoFillBackground(True)
        self.setPalette(bg)

        self.yellow = Yellow(self)

class App(QMainWindow):

    def __init__(self):
        super().__init__()
        self.title = 'PyQt5'
        self.left = 10
        self.top = 10
        self.width = 200
        self.height = 200 
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.green = Green(self)
        self.green.resize(184, 154)
        self.green.move(10, 10)

        self.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)

    ex = App()
    sys.exit(app.exec_())

Solution

  • Use a Layout:

    class Green(QWidget):
    
        def __init__(self, *args):
            super().__init__(*args)
    
            # Set palette
            bg = QPalette()
            bg.setColor(QPalette.Window, Qt.green)
            self.setAutoFillBackground(True)
            self.setPalette(bg)
    
            self.yellow = Yellow(self)
            self.myLayout = QGridLayout()
            self.myLayout.addWidget(self.yellow)
            self.setLayout(self.myLayout)
    

    Result:

    result

    If you add self.myLayout.setContentsMargins(0,0,0,0) the yellow widget completely covers the green one:

    result2