Reputation: 1632
I want to click a button and clear around 20 QLineEdits.
I am trying to use findChildren() and put all the QLineEdit in a QListWidget
self.StudentAdmissionLayout = QGridLayout()
self.StudentAdmissionLayout.addWidget(self.StudentName,1,0,1,1)
The self.StudentAdmissionLayout layout has all the QLineEdit placed on it.
self.myList = QListWidget()
self.Item = QListWidgetItem()
self.Item = self.StudentAdmissionLayout.findChildren(QLineEdit)
self.myList.addItem(self.Item)
I am getting below error:
TypeError: arguments did not match any overloaded call:
QListWidget.addItem(QListWidgetItem): argument 1 has unexpected type 'list'
QListWidget.addItem(QString): argument 1 has unexpected type 'list'
I am trying to put the above 4 lines in a loop. But the 3rd line isn't working, I am not sure how to make it work. Please suggest.
Upvotes: 6
Views: 26361
Reputation: 3450
OK, we have to understand behavior of list-of-QObject QObject.findChildren (self, type type, QString name = QString())
. The documentation for this class says
Returns all children of this object with the given name that can be cast to type T, or an empty list if there are no such objects. Omitting the name argument causes all object names to be matched. The search is performed recursively.
Source: http://pyqt.sourceforge.net/Docs/PyQt4/qobject.html#findChildren
Then, it returns a Python list
to you and each element in the list is type of T (the type you provided as input). So your problem:
TypeError: arguments did not match any overloaded call: QListWidget.addItem(QListWidgetItem): argument 1 has unexpected type 'list' QListWidget.addItem(QString): argument 1 has unexpected type 'list'
is because you pass a list, but addItem
requires a QListWidgetItem
or QString
(or Python str
). If you want to pass a Python list
you must use a for
loop to iterate over the data:
myQListWidget = QListWidget()
listsItem = ['my', 'data', 'are', 'here', '!']
for item in listsItem:
myQListWidget.addItem(item)
Another problem I found is that your search data are QLineEdit
s , It isn’t a supported type in any overloaded method of QListWidget.addItem()
. I think you can't pass it in to this method. But if you need the "text" in each QLineEdit
only, you can convert it like this:
self.studentAdmissionQGridLayout = QGridLayout()
.
.
.
self.myQListWidget = QListWidget()
listsMyQLineEdit = self.studentAdmissionQGridLayout.findChildren(QLineEdit)
for myQLineEdit in listsMyQLineEdit:
self.myQListWidget.addItem(myQLineEdit.text())
Here is a reference to help to understand QListWidget.addItem()
:
http://pyqt.sourceforge.net/Docs/PyQt4/qlistwidget.html#addItem
Upvotes: 11
Reputation: 879
So i ended up wanting to be able to loop through all the child objects from a uic module loaded and link them up dynamically and this loop may be of help for you with some slight mods for only the qlineedit ones
for name, obj in dict(self.__dict__).items():
# print(str(name) + str(obj))
obj_type = str(obj).strip("<PyQt5").rsplit(" ")[0].replace(".", '', 1)
# obj_type = str(obj).strip("<").rsplit(" ")[0]
# print(obj_type)
# obj_type = obj_str.strip("<PyQt5").rsplit(" ")[0].replace(".", '', 1)
label_name = "self." + str(name)
try:
label_name = self.findChild(eval(obj_type), name)
print(str(label_name) + ' created')
except:
pass
if not isinstance(obj_type, QObject):
continue
The full code for stub i used to be able to load Qt Designer uic file and connect up custom slots and signals and live test is below
from PyQt5 import uic, QtWidgets
import sys
from PyQt5.QtCore import QObject
qtCreatorFile = "mainwindow.ui" # Type your file path
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)
class build(Ui_MainWindow, QtWidgets.QMainWindow):
def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.setupUi(self)
for name, obj in dict(self.__dict__).items():
# print(str(name) + str(obj))
obj_type = str(obj).strip("<PyQt5").rsplit(" ")[0].replace(".", '', 1)
# obj_type = str(obj).strip("<").rsplit(" ")[0]
# print(obj_type)
# obj_type = obj_str.strip("<PyQt5").rsplit(" ")[0].replace(".", '', 1)
label_name = "self." + str(name)
try:
label_name = self.findChild(eval(obj_type), name)
print(str(label_name) + ' created')
except:
pass
if not isinstance(obj_type, QObject):
continue
def start():
app = QtWidgets.QApplication(sys.argv)
bld = build()
bld.show()
sys.exit(app.exec_())
if __name__ == '__main__':
start()
Upvotes: 2
Reputation: 120588
If the line-edits do not have the layout as parent, findChildren
will not find them.
It may be better to iterate over the layout something like this:
for row in range(layout.rowCount()):
for column in range(layout.columnCount()):
item = layout.itemAtPosition(row, column)
if item is not None:
widget = item.widget()
if isinstance(widget, QLineEdit):
listWidget.addItem(widget.text())
Upvotes: 4