Search code examples
pythonpysideqtwidgets

QFormLayout does not expand width of left column widgets


I'm trying to create a form layout in a Right-to-left application. I think that the expanding fields grow flag is not working because the most common usage is having the input fields at the right side. Some input widgets do not have the expanding width policy working and they look bad. What could I do?

application demo screenshot

Demo code:

from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QFormLayout, QLabel, QLineEdit, QSpinBox


class FormLayoutDemo(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)

        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)

        self.central_layout = QFormLayout()

        # This does not seem to work :(
        self.central_layout.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy.ExpandingFieldsGrow)

        self.central_widget.setLayout(self.central_layout)

        self.name_label = QLabel("Name")
        self.name_input = QLineEdit()
        self.central_layout.addRow(self.name_input, self.name_label)

        self.age_label = QLabel("Age")
        self.age_input = QSpinBox()
        # Also not working
        self.age_input.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        self.central_layout.addRow(self.age_input, self.age_label)


if __name__ == "__main__":
    app = QApplication()
    main_window = FormLayoutDemo()
    main_window.show()
    app.exec()

Solution

  • QFormLayout treats the first widget in the row as the label and the second as the field, so given that you swapped them, the fieldGrowthPolicy is being applied to the QLabel widgets. Additionally, the size policy of items with the LabelRole are probably managed internally by QFormLayout, so setting it on the widget won't have an effect either.

    Instead set the layoutDirection of its parent widget to RightToLeft and then use the form layout as usual with the labels first and the fields second.

    class FormLayoutDemo(QMainWindow):
        def __init__(self):
            QMainWindow.__init__(self)
            self.central_widget = QWidget()
            
            self.central_widget.setLayoutDirection(Qt.RightToLeft)
            
            self.setCentralWidget(self.central_widget)
            self.central_layout = QFormLayout()
            self.central_widget.setLayout(self.central_layout)
    
            self.name_label = QLabel("Name")
            self.name_input = QLineEdit()
            self.central_layout.addRow(self.name_label, self.name_input)
    
            self.age_label = QLabel("Age")
            self.age_input = QSpinBox()
            self.central_layout.addRow(self.age_label, self.age_input)