Извлечение данных из динамически генерируемых виджетов 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 шт):
Чудно вы пишите, но оно работает.
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())
В дополнение, как вариант решения был предложен такой способ, вдруг кому то будет полезно:
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)
