如何使用findChildren?
我想点击一个按钮,然后清空大约20个QLineEdit。
我正在尝试使用findChildren()方法,把所有的QLineEdit放到一个QListWidget里。
self.StudentAdmissionLayout = QGridLayout()
self.StudentAdmissionLayout.addWidget(self.StudentName,1,0,1,1)
self.StudentAdmissionLayout布局里放着所有的QLineEdit。
self.myList = QListWidget()
self.Item = QListWidgetItem()
self.Item = self.StudentAdmissionLayout.findChildren(QLineEdit)
self.myList.addItem(self.Item)
我遇到了下面的错误:
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'
我想把上面的4行放进一个循环里。但是第三行没有工作,我不太确定怎么才能让它正常运行。请给点建议。
3 个回答
所以我想要能够遍历一个加载的uic模块中的所有子对象,并动态地将它们连接起来。这个循环可能对你有帮助,只需要对qlineedit的部分做一些小修改。
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
下面是我用来加载Qt Designer的uic文件、连接自定义的槽和信号,以及进行实时测试的完整代码。
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()
如果行编辑的布局不是它的父级,findChildren
就找不到它们。
可能更好的做法是像这样遍历布局:
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())
好的,我们需要了解一下 list-of-QObject QObject.findChildren (self, type type, QString name = QString())
的行为。这个类的文档是这么说的:
返回这个对象的所有子对象,这些子对象的名字符合给定的名字,并且可以转换为类型 T。如果没有这样的对象,就返回一个空列表。如果不提供名字参数,则会匹配所有对象的名字。搜索是递归进行的。
来源: http://pyqt.sourceforge.net/Docs/PyQt4/qobject.html#findChildren
然后,它会返回一个 Python 的 list
,列表中的每个元素都是你输入的类型 T。所以你的问题:
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'
是因为你传入了一个列表,但 addItem
需要的是 QListWidgetItem
或 QString
(或者 Python 的 str
)。如果你想传入一个 Python 的 list
,你必须使用 for
循环来遍历数据:
myQListWidget = QListWidget()
listsItem = ['my', 'data', 'are', 'here', '!']
for item in listsItem:
myQListWidget.addItem(item)
我发现的另一个问题是,你的搜索数据是 QLineEdit
,这不是 QListWidget.addItem()
的任何重载方法支持的类型。我认为你不能把它传入这个方法。不过,如果你只需要每个 QLineEdit
中的“文本”,你可以这样转换:
self.studentAdmissionQGridLayout = QGridLayout()
.
.
.
self.myQListWidget = QListWidget()
listsMyQLineEdit = self.studentAdmissionQGridLayout.findChildren(QLineEdit)
for myQLineEdit in listsMyQLineEdit:
self.myQListWidget.addItem(myQLineEdit.text())
这里有一个参考资料,可以帮助你理解 QListWidget.addItem()
:
http://pyqt.sourceforge.net/Docs/PyQt4/qlistwidget.html#addItem