简体   繁体   中英

Search/Filter custom Widgets for QListWidget

How can I search/filter custom widgets in the QListWidget?

For example, I have a custom form widget,

class MetadataForm(QtWidgets.QWidget):
    def __init__(self, data, parent=None):
        super(MetadataForm, self).__init__(parent)

        self.ui = Ui_MetaInfo()
        self.ui.setupUi(self)
        self.data = data
        self.keywords = data['keywords']

        self.ui.pkg_name.setText(self.data['name'])
        self.ui.pkg_version.setText(self.data['version'])
        self.ui.pkg_desc.setText(self.data['desc'])
        self.ui.pkg_author_lbl.setText(self.data['author'])
        self.ui.pkg_pubdate_lbl.setText(self.data['pub_date'])

        self.ui.install_btn.clicked.connect(self.install_pkg)

    def install_pkg(self):
        print('hello from {}'.format(self.data['name']))

I can add these to my MainWindow

class MainWindow(QtWidgets.QDialog):
    def __init__(self, data, parent=None):
        super(MainWindow, self).__init__(parent)
        self.data = data
        self.ui = Ui_Main()
        self.ui.setupUi(self)
        self.set_catalog_data()

    def set_catalog_data(self):
        for item in self.data:
            # print(item)
            metadata = MetadataForm(item)
            print(metadata.keywords)
            lst_item = QtWidgets.QListWidgetItem()
            self.ui.catalog_list_wid.insertItem(
                self.ui.catalog_list_wid.count(),
                lst_item
            )
            self.ui.catalog_list_wid.setItemWidget(lst_item, metadata)
            lst_item.setSizeHint(metadata.sizeHint())

In my MainWindow my UI has a QLineEdit, named self.ui.search_box , how can I filter my custom QListWidgetItem based the keywords attribute of my Metadata class?

Some simple testing data:

test_data = [
    {
        'name': 'Foo Model',
        'version': 'v1.0.0.1',
        'desc': lorem.paragraph(),
        'author': 'Jane Doe',
        'pub_date': '10/14/2018',
        'keywords': ['foo']
    },
    {
        'name': 'Bar Model',
        'version': 'v1.0.0.1',
        'desc': lorem.paragraph(),
        'author': 'Jon Smith',
        'pub_date': '11/2/2018',
        'keywords': ['bar']
    }
]

You just have to iterate over the rows and get keyword using the item () method to get the QListWidgetItem and then itemWidget to get the widget, using widget you get keywords and apply the filter, if you meet the filter it becomes visible otherwise you must hide

class MainWindow(QtWidgets.QDialog):
    def __init__(self, data, parent=None):
        super(MainWindow, self).__init__(parent)
        self.data = data
        self.ui = Ui_Main()
        self.ui.setupUi(self)
        self.ui.search_box.textChanged.connect(self.on_textChanged)
        self.set_catalog_data()

    def set_catalog_data(self):
        for item in self.data:
            # print(item)
            metadata = MetadataForm(item)
            lst_item = QtWidgets.QListWidgetItem()
            self.ui.catalog_list_wid.insertItem(
                self.ui.catalog_list_wid.count(),
                lst_item
            )
            self.ui.catalog_list_wid.setItemWidget(lst_item, metadata)
            lst_item.setSizeHint(metadata.sizeHint())

    @QtCore.pyqtSlot(str)
    def on_textChanged(self, text):
        for row in range(self.ui.catalog_list_wid.count()):
            it = self.ui.catalog_list_wid.item(row)
            widget = self.ui.catalog_list_wid.itemWidget(it)
            if text: 
                it.setHidden(not self.filter(text, widget.keywords))
            else:
                it.setHidden(False)

    def filter(self, text, keywords):
        # foo filter
        # in the example the text must be in keywords
        return text in keywords

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM