PyQt5使用布局将其他小部件添加到小部件子类?

问题描述

我试图将QListWidget子类化,并在其上方添加一个搜索框。我知道我可以通过将QWidget子类化并为其提供包含QListWidgetQLineEdit的布局来创建它,但是我宁愿它是QListWidget的直接子类因此它可以轻松替换代码中现有的QListWidgets,并保留父窗口小部件可能调用的所有继承方法。

这是我的尝试,但是我不确定如何将QListWidgetQLineEdit放入布局中,layout.addWidget(self)无效。

import re
from PyQt5 import QtCore,QtGui,QtWidgets


class SearchableListWidget(QtWidgets.QListWidget):
    def __init__(self,items,parent=None):
        super().__init__(parent=parent)

        self.initial_items = items
        self.set_items(items)

        self.search_box = QtWidgets.QLineEdit()
        self.search_box.textChanged.connect(self.filter)

        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(self.search_box)
        self.setLayout(layout)

    def filter(self):
        filtered_items = [item for item in self.initial_items
                          if re.search(self.search_box.text().lower(),item.lower())]

        self.set_items(filtered_items)

    def get_items(self):
        return [str(self.item(i).text()) for i in range(self.count())]

    def set_items(self,items):
        self.clear()
        for name in items:
            self.addItem(name)


if __name__ == "__main__":
    import sys
    from PyQt5.QtWidgets import QApplication

    app = QApplication(sys.argv)

    test = SearchableListWidget(['a','b','c'])
    test.show()

    sys.exit(app.exec_())

我得到的是什么:

enter image description here

我想要什么:

enter image description here

解决方法

问题在于程序的结构:窗口是SearchableListWidget,它是一个QListWidget,您在其中通过布局放置了QLineEdit,但是正确的做法是创建一个从类似QWidget的容器​​继承的类,并在其中放置通过QVBoxLayout垂直放置QLineEdit和QListWidget:

import re
from PyQt5 import QtCore,QtGui,QtWidgets


class SearchableWidget(QtWidgets.QWidget):
    def __init__(self,items,parent=None):
        super().__init__(parent)

        self.search_box = QtWidgets.QLineEdit()
        self.search_box.textChanged.connect(self.filter)

        self.list_widget = QtWidgets.QListWidget()

        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(self.search_box)
        layout.addWidget(self.list_widget)

        self.initial_items = items
        self.set_items(items)

    def filter(self):
        filtered_items = [
            item
            for item in self.initial_items
            if re.search(self.search_box.text().lower(),item.lower())
        ]

        self.set_items(filtered_items)

    def get_items(self):
        return [
            str(self.list_widget.item(i).text())
            for i in range(self.list_widget.count())
        ]

    def set_items(self,items):
        self.list_widget.clear()
        for name in items:
            self.list_widget.addItem(name)


if __name__ == "__main__":
    import sys
    from PyQt5.QtWidgets import QApplication

    app = QApplication(sys.argv)

    test = SearchableWidget(["a","b","c"])
    test.show()

    sys.exit(app.exec_())

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...