Как обратиться к полям QLineEdit, созданным динамически в PyQt5

Делаю небольшую программку, в которой используются вкладки с одинаковым содержимым (QLineEdit). Вкладки создаются по нажатию на кнопку "Добавить" и в каждой вкладке создаются однотипные поля для заполнения. Создание вкладки реализовано отдельным классом. По нажатию кнопки Добавить создается экземпляр класса, где прописаны параметры полей и заголовков.

Вопрос заключается в том, что экземпляры полей QLineEdit имеют одинаковое имя (self.lineEdit) и я не понимаю как мне получить данные, которые я внесу в эти поля после создания новой вкладки?

Если использовать QT Designer, то в нем после создания поля этому полю присваивается уникальное имя, например self.lineEdit_1, self.lineEdit_2 и т.п. и можно легко получить введенное значение в эти поля.

Добавил рабочую версию кода, в которой создаются вкладки с полями. Если нажать кнопку "Печать в консоль", то напечатается только текст введенный в поле "Характеристики" и это понятно, т.к. это поле было создано последним и у всех полей во вкладке нет уникального идентификатора. Еще и вкладок может быть несколько, если они все будут заполнены, то мне нужно будет из всех полей забирать данные (в этом случае думаю можно циклом пройти по вкладкам).

Пример класса, где прописаны параметры создаваемых полей и заголовков:

import sys
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtWidgets import (QLineEdit, QLabel, QSpinBox, QWidget, QProgressBar, QPushButton, QApplication)
from PyQt5.QtCore import QRect
from PyQt5.QtGui import QFont

class TabPage(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.initUI()

    def initUI(self):

        font_8 = QFont()
        font_8.setFamily("MS Shell Dlg 2")
        font_8.setPointSize(8)
        font_8.setBold(False)
        font_8.setWeight(50)

        font_12 = QFont()
        font_12.setFamily("Calibri")
        font_12.setPointSize(12)
        font_12.setBold(False)
        font_12.setWeight(50)

        self.label = QLabel("№ типа", self)
        self.label.setGeometry(QRect(10, 10, 141, 16))
        self.label.setFont(font_8)
        self.lineEdit = QLineEdit(self)
        self.lineEdit.setGeometry(QRect(10, 30, 191, 31))
        self.lineEdit.setFont(font_12)
        self.lineEdit.setFocusPolicy(QtCore.Qt.ClickFocus)
        self.lineEdit.setClearButtonEnabled(True)

        self.spinBox = QSpinBox(self)
        self.spinBox.setGeometry(QRect(240, 30, 191, 31))

        self.spinBox.setFont(font_12)
        self.spinBox.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
        self.spinBox.setFocusPolicy(QtCore.Qt.ClickFocus)
        self.spinBox.setWhatsThis("")
        self.spinBox.setAccessibleName("")
        self.spinBox.setAlignment(QtCore.Qt.AlignCenter)
        self.spinBox.setMinimum(1917)
        self.spinBox.setMaximum(2060)
        self.spinBox.setProperty("value", 2020)
        self.label = QLabel("Год выпуска *", self)
        self.label.setGeometry(QRect(240, 10, 141, 16))
        self.label.setFont(font_8)

        self.label = QLabel("Зав №", self)
        self.label.setGeometry(QRect(470, 10, 141, 16))
        self.label.setFont(font_8)

        self.lineEdit = QLineEdit(self)
        self.lineEdit.setGeometry(QRect(470, 30, 191, 31))
        self.lineEdit.setFont(font_12)
        self.lineEdit.setFocusPolicy(QtCore.Qt.ClickFocus)
        self.lineEdit.setClearButtonEnabled(True)

        self.lineEdit = QLineEdit(self)
        self.lineEdit.setGeometry(QRect(10, 90, 651, 31))
        self.lineEdit.setFont(font_12)
        self.lineEdit.setFocusPolicy(QtCore.Qt.ClickFocus)
        self.lineEdit.setClearButtonEnabled(True)

        self.label = QLabel("Характеристики", self)
        self.label.setGeometry(QRect(10, 70, 211, 16))
        self.label.setFont(font_8)

        self.btn = QPushButton('Печать в консоль', self)
        self.btn.move(40, 150)
        self.btn.clicked.connect(self.doAction)

        self.show()


    def doAction(self):
        print(self.lineEdit.text())


class Window(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.tabs = QtWidgets.QTabWidget()
        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(self.tabs)
        button = QtWidgets.QToolButton()
        button.setToolTip('Add New Tab')
        button.clicked.connect(self.addNewTab)
        button.setIcon(self.style().standardIcon(
            QtWidgets.QStyle.SP_DialogYesButton))
        self.tabs.setCornerWidget(button, QtCore.Qt.TopRightCorner)
        self.addNewTab()

    def addNewTab(self):
        text = 'Tab %d' % (self.tabs.count() + 1)
        self.tabs.addTab(TabPage(self.tabs), text)

if __name__ == '__main__':

    app = QtWidgets.QApplication(sys.argv)
    window = Window()
    window.setGeometry(700, 300, 700, 300)
    window.show()
    sys.exit(app.exec_())

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

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

Нет, одинаковых имен (self.label, self.lineEdit) не должно быть. Я немного упорядочил ваш код и добавил в него функциональности.

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.Qt import *


class TabPage_SO(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.labelType = QLabel("№ типа", self)
        self.lineEditType = QLineEdit(self)
        self.lineEditType.setClearButtonEnabled(True)

        self.labelYearOfIssue = QLabel("Год выпуска *", self)
        self.spinBox = QSpinBox(self)
        self.spinBox.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
        self.spinBox.setAlignment(QtCore.Qt.AlignCenter)
        self.spinBox.setMinimum(1917)
        self.spinBox.setMaximum(2060)
        self.spinBox.setProperty("value", 2020)

        self.labelSerialNumber = QLabel("Заводской №", self)
        self.lineEditSerialNumber = QLineEdit(self)
        self.lineEditSerialNumber.setClearButtonEnabled(True)

        self.labelSpecifications = QLabel("Характеристики", self)
        self.lineEditSpecifications = QLineEdit(self)
        self.lineEditSpecifications.setClearButtonEnabled(True)

        grid = QGridLayout(self) 
        grid.addWidget(self.labelType, 0, 0)
        grid.addWidget(self.labelYearOfIssue, 0, 1)
        grid.addWidget(self.labelSerialNumber, 0, 2)
        grid.addWidget(self.lineEditType, 1, 0)
        grid.addWidget(self.spinBox, 1, 1)
        grid.addWidget(self.lineEditSerialNumber, 1, 2)
        grid.addWidget(self.labelSpecifications, 2, 0)
        grid.addWidget(self.lineEditSpecifications, 3, 0, 1, 3)
        grid.setRowStretch(4, 1)


class TabWidget(QTabWidget):
    def __init__(self):
        super().__init__()
        self.addTab(TabPage_SO(self), "Tab Zero") 
        count = self.count()
        nb = QToolButton(text="Добавить", autoRaise=True)     
        nb.clicked.connect(self.new_tab)
        self.insertTab(count, QWidget(), "")
        self.tabBar().setTabButton(count, QTabBar.RightSide, nb)

    def new_tab(self):
        index = self.count() - 1
        self.insertTab(index, TabPage_SO(self), "Tab %d" % index)
        self.setCurrentIndex(index)


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.centralWidget = QWidget()
        self.setCentralWidget(self.centralWidget)
        
        self.tabWidget = TabWidget()
        self.tableWidget = QTableWidget(0, 4)
        self.tableWidget.setHorizontalHeaderLabels(
            ["№ типа", "Год выпуска *", "Заводской №", "Характеристики"])
        self.tableWidget.horizontalHeader().setSectionResizeMode(3, QHeaderView.Stretch)
        self.tableWidget.setSortingEnabled(True)
        self.tableWidget.setAlternatingRowColors(True)

        self.buttonAdd = QPushButton('Добавить из текущей вкладки в таблицу')
        self.buttonAdd.clicked.connect(self.addRowTable)
        self.buttonDel = QPushButton('Удалить выбранную строку в таблице')
        self.buttonDel.clicked.connect(self.delRowTable)

        vbox = QGridLayout(self.centralWidget)
        vbox.addWidget(self.tabWidget, 0, 0, 1, 2)
        vbox.addWidget(self.tableWidget, 1, 0, 1, 2)
        vbox.addWidget(self.buttonAdd, 2, 0)
        vbox.addWidget(self.buttonDel, 2, 1)
        
        
    def addRowTable(self):
        editType = self.tabWidget.currentWidget().lineEditType.text() 
        spinYearOfIssue = str(self.tabWidget.currentWidget().spinBox.value())
        editSerialNumber = self.tabWidget.currentWidget().lineEditSerialNumber.text()
        editSpecifications = self.tabWidget.currentWidget().lineEditSpecifications.text()
        
        if not editType or not editSerialNumber or not editSpecifications:
            msg = QMessageBox.information(self, 'Внимание', 'Заполните все поля!')
            return
        self.tableWidget.setSortingEnabled(False)
        rows = self.tableWidget.rowCount()
        self.tableWidget.insertRow(rows)
        self.tableWidget.setItem(rows, 0, QTableWidgetItem(editType)) 
        self.tableWidget.setItem(rows, 1, QTableWidgetItem(spinYearOfIssue))  
        self.tableWidget.setItem(rows, 2, QTableWidgetItem(editSerialNumber)) 
        self.tableWidget.setItem(rows, 3, QTableWidgetItem(editSpecifications))          
        self.tableWidget.setSortingEnabled(True)
        #print(editType, spinYearOfIssue, editSerialNumber, editSpecifications)    

    def delRowTable(self):
        row = self.tableWidget.currentRow()
        if row == -1:
            msg = QMessageBox.information(self, 'Внимание', 'Выберите строку для удаления')
            return
        self.tableWidget.removeRow(row)    
       

qss = """
QLabel {
    font: 8pt "MS Shell Dlg 2";
}
QLineEdit {
    font: 12pt "Calibri";
}
QSpinBox {
    font: 12pt "Calibri";
}
""" 


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    app.setStyleSheet(qss)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

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

→ Ссылка