如何使用findChildren?

5 投票
3 回答
24390 浏览
提问于 2025-04-18 16:16

我想点击一个按钮,然后清空大约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 个回答

2

所以我想要能够遍历一个加载的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()
4

如果行编辑的布局不是它的父级,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())
11

好的,我们需要了解一下 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 需要的是 QListWidgetItemQString(或者 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

撰写回答