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

时间:2020-08-11 01:52:44

标签: python pyqt 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

1 个答案:

答案 0 :(得分:1)

问题在于程序的结构:窗口是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_())