Reputation: 82
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
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:
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;Upvotes: 1