Search code examples
pythonpyqt5mayapyside2

PyQt 5: How to maintain relative widget size when expanding a window


I'm working on a custom ui in Maya 2018 which uses PyQt5 (via PySide2 - there are some minimal differences, but it's essentially PyQt5).

I've got a QHBoxLayout with two widgets in it and their sizing policies are both set to 'expanding'. I set the minimum width of one of them to be about twice as wide as the other.

Whenever I expand the window, the smaller widget expands until it's the same size as the larger one (which doesn't change size at all)... and then they both continue to expand at the same rate - both taking up half of the window.

I would prefer they maintain their sizes relative to each other throughout the whole expansion.

Is there a way to do this that I'm just completely overlooking?

Here's some simplified code I whipped up to reproduce the issue:

import PySide2.QtWidgets as QtWidgets

class TestDialog(QtWidgets.QDialog):
    def __init__(self, *args, **kwargs):
        QtWidgets.QDialog.__init__(self, *args, **kwargs)

        main_layout = QtWidgets.QHBoxLayout()
        self.setLayout(main_layout)
        main_layout.setContentsMargins(5, 5, 5, 5)
        main_layout.setSpacing(5)

        w1 = QtWidgets.QPushButton('small')
        w2 = QtWidgets.QPushButton('large')
        w1.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        w2.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        w2.setMinimumWidth(250)

        main_layout.addWidget(w1)
        main_layout.addWidget(w2)

        self.setMinimumWidth(450)
        self.setMinimumHeight(100)
        self.resize(450, 100)


test = TestDialog()
test.show()

Solution

  • If you want the relationship between the widths to be maintained then you must set the stretch by adding the widgets:

    from PySide2 import QtWidgets
    
    
    class TestDialog(QtWidgets.QDialog):
        def __init__(self, *args, **kwargs):
            super(TestDialog, self).__init__(*args, **kwargs)
    
            main_layout = QtWidgets.QHBoxLayout(self)
    
            main_layout.setContentsMargins(5, 5, 5, 5)
            main_layout.setSpacing(5)
    
            w1 = QtWidgets.QPushButton("small")
            w2 = QtWidgets.QPushButton("large")
            w1.setSizePolicy(
                QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding
            )
            w2.setSizePolicy(
                QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding
            )
    
            main_layout.addWidget(w1, stretch=1)
            main_layout.addWidget(w2, stretch=2)
    
            self.setMinimumSize(450, 100)
            self.resize(450, 100)
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
        test = TestDialog()
        test.show()
        sys.exit(app.exec_())