Извлечение данных из динамически генерируемых виджетов PyQt

Как можно получить текст из динамически генерируемых QLineEdit в PyQT5/PyQT6?
Я смог извлечь текст только из последнего созданного виджета, но я бы хотел проверять все созданные виджеты и извлекать все данные, где QLineEdit не пустое - и компоновать данные в список например.

Вот минимально воспроизводимый пример:

import sys
from PyQt6.QtWidgets import QWidget, QApplication, QGridLayout, QHBoxLayout, QPushButton, QLineEdit


class Main(QWidget):
    def __init__(self):
        super().__init__()
        self.row_counter = 0
        self.le = ''
        self.grid = QGridLayout()
        self.grid_line_url = QGridLayout()
        self.grid.addLayout(self.generate_line_url(), 0, 0)
        self.grid.addWidget(self.push_button(name='ok!',
                                        do=self.text_from_line_edit), 1, 0)
        self.setLayout(self.grid)

    def h_box(self, *args):
        box = QHBoxLayout()
        if args:
            for widget in args:
                box.addWidget(widget)
        return box

    def push_button(self, width=None, height=None, name=None, do=None):
        but = QPushButton()
        if width is not None and height is not None:
            but.setFixedSize(width, height)
        if name:
            but.setText(name)
        if do:
            but.clicked.connect(do)
        return but

    def line_edit(self):
        self.le = QLineEdit()
        self.le.setFixedHeight(30)
        return self.le

    def generate_line_url(self):
        self.grid_line_url.addLayout(self.h_box(self.line_edit(),
                                           self.push_button(width=30,
                                                       height=30,
                                                       name='+',
                                                       do=self.generate_line_url)), self.row_counter, 0, 1, 3)
        self.row_counter += 1
        return self.grid_line_url



    def text_from_line_edit(self):
        print(self.le.text())


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Main()
    w.show()
    sys.exit(app.exec())

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

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

Чудно вы пишите, но оно работает.

template QList QObject::findChildren(const QString &name, >Qt::FindChildOptions options = Qt::FindChildrenRecursively) const

...

Этот пример возвращает все QPushButtons, которые являются дочерними элементами родительского Widget:

QList<QPushButton *> allPButtons = parentWidget.findChildren<QPushButton *>();

...

main.py

import sys
'''
from PyQt6.QtWidgets import QWidget, QApplication, QGridLayout, \
    QHBoxLayout, QPushButton, QLineEdit
'''
from PyQt5.Qt import *


class Main(QWidget):
    def __init__(self):
        super().__init__()
        
        self.row_counter = 0
        self.le = ''
        self.lineEdits = []                                                  # +
        
        self.grid = QGridLayout()
        self.grid_line_url = QGridLayout()
        self.grid.addLayout(self.generate_line_url(), 0, 0)
        self.grid.addWidget(self.push_button(
            name='ok!',
            do=self.text_from_line_edit), 1, 0)
        self.setLayout(self.grid)

    def h_box(self, *args):
        box = QHBoxLayout()
        if args:
            for widget in args:
                box.addWidget(widget)
        return box

    def push_button(self, width=None, height=None, name=None, do=None):
        but = QPushButton()
        if width is not None and height is not None:
            but.setFixedSize(width, height)
        if name:
            but.setText(name)
        if do:
            but.clicked.connect(do)
        return but

    def line_edit(self):
# -----> vvvv <-------------- self, при динамически создаваемых объектах - не нужен
#        self.le = QLineEdit()
        le = QLineEdit()
        le.setObjectName(f'le_{self.row_counter}')                           # +
        le.setFixedHeight(30)
        return le

    def generate_line_url(self):
        self.grid_line_url.addLayout(
            self.h_box(self.line_edit(),
                       self.push_button(
                           width=30,
                           height=30,
                           name='+',
                           do=self.generate_line_url
                       )
            ), self.row_counter, 0, 1, 3)
        self.row_counter += 1
        return self.grid_line_url

    def text_from_line_edit(self):
        self.lineEdits =  self.findChildren(QLineEdit)                   # !!! +++ 
        for lineEdit in self.lineEdits:                                  # !!! +++ 
            print(f'{lineEdit.objectName()}: {lineEdit.text()}')


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Main()
    w.show()
    sys.exit(app.exec())

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

→ Ссылка
Автор решения: Djony Cooper

В дополнение, как вариант решения был предложен такой способ, вдруг кому то будет полезно:

def text_from_line_edit(self):
    url_box = []
    for i in self.children():
        if type(i).__name__=='QLineEdit' and i.text() != '':
               url_box.append(i.text())
    print(url_box)

→ Ссылка