Cerdipinki
Cerdipinki

Reputation: 82

How to add more rows in a QFormLayout when you push a button

I'm making a database editor using PySide6. I made a QPushButton to add 2 rows in a QFormLayout. See screenshot 1

Looks good right? That is what it looked like before you click "Add another column". But then I click and instead of making 2 more rows, it moves them to the end See screenshot 2

Here is my code:

def addTableForm(self):
    def addColumnForm():
        layout.addRow(columnNameLabel, columnName)
        layout.addRow(columnTypeLabel, columnType)
    layout = QFormLayout(self)
    widget = QWidget(self)
    tableNameLabel = QLabel(parent=self, text="Enter the table name")
    tableName = QLineEdit(parent=self)
    columnNameLabel = QLabel(parent=self, text="Add a column")
    columnName = QLineEdit(parent=self)
    columnTypeLabel = QLabel(parent=self, text="Enter the type of the column")
    columnType = QLineEdit(parent=self)
    moreColumnsLabel = QLabel(parent=self, text="Add another column")
    moreColumns = QPushButton(parent=self, text="Add another column", clicked=addColumnForm)
    moreColumns.setFixedWidth(200)
    cancel = QPushButton(self, text="Cancel", clicked=self.selectTables)
    confirm = QPushButton(self, text="Confirm")
    layout.addRow(tableNameLabel, tableName)
    addColumnForm()
    layout.addRow(moreColumnsLabel, moreColumns)
    layout.addRow(cancel, confirm)
    widget.setLayout(layout)
    self.setCentralWidget(widget)

The function is inside a MainWindow class, heir to QMainWindow. Can you please help me out? By the way, can you please also give me some styling tips? I don't like the way how all the widgets are crammed together.

Thanks

Upvotes: 1

Views: 1443

Answers (1)

musicamante
musicamante

Reputation: 48260

Widgets are unique instances, they are not "duplicated" if you try to add them again to a layout.
In fact, you are not adding new widgets, you're just telling the layout to add a row with the given widgets, and since those widgets already are in the layout, the result is that they get removed, and added to "new" rows, which results in shifting them.

What you need is to dynamically create new widgets, and since you're probably going to need their contents, you should keep their references.

A possible implementation could be the following:

def addTableForm(self):
    columnWidgets = []
    def addColumnForm():
        row = layout.rowCount()
        columnName = QLineEdit()
        layout.insertRow(row, "Add a column", columnName)
        columnType = QLineEdit()
        layout.insertRow(row + 1, "Enter the type of the column", columnType)
        columnWidgets.append((columnName, columnType))

    def getColumnData():
        return [(n.text(), t.text()) for n, t in columnWidgets]

    widget = QWidget()
    layout = QFormLayout(widget)
    tableName = QLineEdit()

    moreColumns = QPushButton(text="Add another column", clicked=addColumnForm)
    moreColumns.setFixedWidth(200)

    layout.addRow("Enter the table name", tableName)
    addColumnForm()
    layout.addRow("Add another column", moreColumns)

    cancel = QPushButton("Cancel", clicked=self.selectTables)
    confirm = QPushButton("Confirm")
    confirm.clicked.connect(lambda: self.createTable(tableName.text(), getColumnData()))

    layout.addRow(cancel, confirm)
    widget.setLayout(layout)
    self.setCentralWidget(widget)

Some notes:

  • you should not use QFormLayout(self) if self is a QMainWindow (which doesn't support setting a layout), since the widget argument of a QLayout constructor is the widget on which the layout will be set; you should use the widget that is going to be used as central widget instead;
  • you don't need to always specify the parent for widgets that are going to be added to a layout: the moment you add those widgets, the parent will take their ownership on its own;
  • unless you need to set specific features, it's not necessary to create QLabels for the first column, just use a string;
  • if the first argument of QPushButton is a string, there's no need to use the keyword;

Upvotes: 1

Related Questions