How to search through a pyqt5 tablewidget and return search results

Heads up! You've already completed this tutorial.

meshelleva4815 | 2020-09-27 13:42:20 UTC | #1

good afternoon guys. I have this tablewidget I created and populated with informations from the database. in the page there is a lineedit I intend using to accept search input. the name or id entered into the lineedit will then be use to search the qtablewidgets, when it finds the results it the highlights that line on the the table. I read through the documentation and saw something like Tablewidget.finditem () I really don't know how to use to do all this I intend doing. pls can you help me with an example?


martin | 2020-09-30 16:58:20 UTC | #2

Hey @meshelleva4815 ...are you actually using a QTableWidget (manually populating from a database) or using a QTableView. If it's the latter you need to implement the search yourself, but if it's the former you can use the .findItems method as you say.

The C++ definition looks like this

python
QList<QTableWidgetItem *> QTableWidget::findItems(const QString &text, Qt::MatchFlags flags) const

This tells us that the method accepts a str "text" to search, and a Qt.MatchFlags object which is what determines how we search. If you take a look at the definition for Qt.MatchFlags you can see the options available -- it covers things like starts with, contains, etc. and whether the search is case sensitive. You can combine some of these together -- e.g. starts with and case sensitive, if you like.

The .findItems method when called will return a list of QTableWidgetItem objects. These objects are the actual data items in the table. Once you have them, you can select a given item by calling .setCurrentItem and passing in an individual item.

Here's a simple example with a small table.

python

from PyQt5.QtWidgets import QTableWidget, QLineEdit, QPushButton, QApplication, QMainWindow, QVBoxLayout, QWidget, QTableWidgetItem
from PyQt5.QtCore import Qt

import random, string


class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()


        self.query = QLineEdit()
        self.query.setPlaceholderText("Search...")
        self.query.textChanged.connect(self.search)

        n_rows = 50
        n_cols = 4

        self.table = QTableWidget()
        self.table.setRowCount(n_rows)
        self.table.setColumnCount(n_cols)

        for c in range(0, n_cols):
            for r in range(0, n_rows):
                s = ''.join(random.choice(string.ascii_lowercase) for n in range(10))
                i = QTableWidgetItem(s)
                self.table.setItem(c, r, i)

        layout = QVBoxLayout()

        layout.addWidget(self.query)
        layout.addWidget(self.table)

        w = QWidget()
        w.setLayout(layout)
        self.setCentralWidget(w)

    def search(self, s):
        items = self.table.findItems(s, Qt.MatchContains)
        if items:  # we have found something
            item = items[0]  # take the first
            self.table.setCurrentItem(item)


app = QApplication([])
w = MainWindow()
w.show()

app.exec_()

If you type a search string in the line input, you'll see the first matching item in the table selected (and highlighted) like below.

Screenshot 2020-09-30 at 18.57.23|514x500

Since the search can return many items, but .setCurrentItem selects only one, you will probably want to provide some mechanism to step through the searches.


meshelleva4815 | 2020-10-04 14:09:22 UTC | #3

thanks really. I think this really help. good we have you here always...😁😁


Well done, you've finished this tutorial! Mark As Complete
[[ user.completed.length ]] completed [[ user.streak+1 ]] day streak