Как добавить новый виджет по нажатию кнопки в PyQt?

Помогите, пожалуйста, найти ошибку в коде.
Почему функция addNewLine() не работает?

По нажатию на кнопку btnAdd, программа должна добавлять новую строку, а по нажатию на btnDell она должна удалять.

Если написать эти три строчки, которые добавляют новую строку, не внутри функции addNewLine(), а внутри конструкции def __init__(self) все работает.

mainwindow.py:

from PyQt6 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(267, 274)

        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(20, 40, 231, 31))
        self.lineEdit.setObjectName("lineEdit")

        self.btnAdd = QtWidgets.QPushButton(self.centralwidget)
        self.btnAdd.setGeometry(QtCore.QRect(90, 220, 81, 31))
        self.btnAdd.setStyleSheet("font: 11pt \"MS Shell Dlg 2\";")
        self.btnAdd.setObjectName("btnAdd")

        self.btnDelete = QtWidgets.QPushButton(self.centralwidget)
        self.btnDelete.setGeometry(QtCore.QRect(170, 220, 81, 31))
        self.btnDelete.setStyleSheet("font: 11pt \"MS Shell Dlg 2\";")
        self.btnDelete.setObjectName("btnDelete")

        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.btnAdd.setText(_translate("MainWindow", "Add"))
        self.btnDelete.setText(_translate("MainWindow", "Delete"))


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec())

main.py:

import sys
from PyQt6 import QtCore, QtGui, QtWidgets
from mainwindow import Ui_MainWindow

class Main(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(Main, self).__init__()
        self.setupUi(self)

        self.btnAdd.clicked.connect(self.printHellow)
        self.btnDelete.clicked.connect(self.addNewLine)

        



    def printHellow(self):
        print("Hello world")

    def addNewLine(self):
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(20, 80, 231, 31))
        self.lineEdit.setObjectName("lineEdit")


if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    application = Main()
    application.show()
    sys.exit(app.exec())

Ответы (1 шт):

Автор решения: S. Nick

Если вы создаете виджет НЕ в конструкторе и хотите его показать, вам надо сделать: lineEdit.show() или добавить его в менеджер компоновки. Второе предпочтительнее.

import sys
'''
from PyQt6 import QtCore, QtGui, QtWidgets                            # PyQt6
'''
from PyQt5 import QtCore, QtGui, QtWidgets                            # PyQt5

#from mainwindow import Ui_MainWindow
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(267, 274)

        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(20, 40, 231, 31))
        self.lineEdit.setObjectName("lineEdit")

        self.btnAdd = QtWidgets.QPushButton(self.centralwidget)
        self.btnAdd.setGeometry(QtCore.QRect(90, 220, 81, 31))
        self.btnAdd.setStyleSheet("font: 11pt \"MS Shell Dlg 2\";")
        self.btnAdd.setObjectName("btnAdd")

        self.btnDelete = QtWidgets.QPushButton(self.centralwidget)
        self.btnDelete.setGeometry(QtCore.QRect(170, 220, 81, 31))
        self.btnDelete.setStyleSheet("font: 11pt \"MS Shell Dlg 2\";")
        self.btnDelete.setObjectName("btnDelete")

        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.btnAdd.setText(_translate("MainWindow", "Add"))
        self.btnDelete.setText(_translate("MainWindow", "Delete"))


class Main(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(Main, self).__init__()
        self.setupUi(self)

# -------------------------------------> vvvvvvvvvv <----------------------
        self.btnAdd.clicked.connect(self.addNewLine)
        self.btnDelete.clicked.connect(self.printHellow)
# +++ vvvvvv        
        self.layout = QtWidgets.QGridLayout(self.centralwidget)
        self.layout.addWidget(self.lineEdit, 0, 0, 1, 2)
        self.layout.addWidget(self.btnAdd, 30, 0, 
            alignment=QtCore.Qt.AlignRight | QtCore.Qt.AlignBottom)
        self.layout.addWidget(self.btnDelete, 30, 1, 
            alignment=QtCore.Qt.AlignLeft | QtCore.Qt.AlignBottom)
# +++ ^^^^^^

    def printHellow(self):
        print("Hello world. Тут будем удалять какую-то строку.")

    def addNewLine(self):
#        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        row = self.layout.count() - 2
        
        lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        lineEdit.setGeometry(QtCore.QRect(20, 80, 231, 31))
        lineEdit.setObjectName("lineEdit{row}")
#        lineEdit.show()

        self.layout.addWidget(lineEdit, row, 0, 1, 2)


if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    application = Main()
    application.show()
    sys.exit(app.exec())

введите сюда описание изображения


Update

У вас на скриншоте строки слишком узкие.
Скажите, пожалуйста, как из расширить строки, они получаются слишком узкие

minimumHeight : int

Это свойство содержит минимальную высоту виджета в пикселях. Это свойство соответствует высоте, содержащейся в свойстве MinimumSize. По умолчанию это свойство имеет значение 0.

import sys
'''
from PyQt6 import QtCore, QtGui, QtWidgets                            # PyQt6
'''
from PyQt5 import QtCore, QtGui, QtWidgets                            # PyQt5

#from mainwindow import Ui_MainWindow
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(267, 274)

        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(20, 40, 231, 31))
        self.lineEdit.setObjectName("lineEdit")

        self.btnAdd = QtWidgets.QPushButton(self.centralwidget)
        self.btnAdd.setGeometry(QtCore.QRect(90, 220, 81, 31))
        self.btnAdd.setStyleSheet("font: 11pt \"MS Shell Dlg 2\";")
        self.btnAdd.setObjectName("btnAdd")

        self.btnDelete = QtWidgets.QPushButton(self.centralwidget)
        self.btnDelete.setGeometry(QtCore.QRect(170, 220, 81, 31))
        self.btnDelete.setStyleSheet("font: 11pt \"MS Shell Dlg 2\";")
        self.btnDelete.setObjectName("btnDelete")

        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.btnAdd.setText(_translate("MainWindow", "Add"))
        self.btnDelete.setText(_translate("MainWindow", "Delete"))


class Main(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(Main, self).__init__()
        self.setupUi(self)

# -------------------------------------> vvvvvvvvvv <----------------------
        self.lineEdit.setMinimumHeight(31)                                  # +++
        
        self.btnAdd.clicked.connect(self.addNewLine)
        self.btnDelete.clicked.connect(self.printHellow)
# +++ vvvvvv        
        self.layout = QtWidgets.QGridLayout(self.centralwidget)
        self.layout.addWidget(self.lineEdit, 0, 0, 1, 2)
        self.layout.addWidget(self.btnAdd, 30, 0, 
            alignment=QtCore.Qt.AlignRight | QtCore.Qt.AlignBottom)
        self.layout.addWidget(self.btnDelete, 30, 1, 
            alignment=QtCore.Qt.AlignLeft | QtCore.Qt.AlignBottom)
# +++ ^^^^^^

    def printHellow(self):
        print("Hello world. Тут будем удалять какую-то строку.")

    def addNewLine(self):
#        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        row = self.layout.count() - 2
        
        lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        
#        lineEdit.setGeometry(QtCore.QRect(20, 80, 231, 31))
        lineEdit.setMinimumHeight(31)                                    # +++
        
        lineEdit.setObjectName("lineEdit{row}")
#        lineEdit.show()

        self.layout.addWidget(lineEdit, row, 0, 1, 2)


if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    application = Main()
    application.show()
    sys.exit(app.exec())

введите сюда описание изображения

→ Ссылка