15

In my application I have QtableWidget displaying multiple rows , line edit to enter string and push button, Requirement says upon clicking on push button Same QTableWidget should show only those rows which are having string entered into line edit.

I thought of using QSortFilterProxy Model but QTableWidget is having setModel(...)method private so I am unable to use QSortFilterProxy Model in this case. Please let me know how to implement Filter option in QTable Widget

Thomas Vincent
  • 2,214
  • 4
  • 17
  • 25
john
  • 185
  • 1
  • 2
  • 6

2 Answers2

27

Using a sort/filter proxy is probably overkill for this anyway.

It's a matter of iterating through all of your QTableWidgetItem objects, determining if their text matches the filter and calling QTableView::setRowHidden() as needed.

For example:

QString filter = textEdit->text();
for( int i = 0; i < table->rowCount(); ++i )
{
    bool match = false;
    for( int j = 0; j < table->columnCount(); ++j )
    {
        QTableWidgetItem *item = table->item( i, j );
        if( item->text().contains(filter) )
        {
            match = true;
            break;
        }
    }
    table->setRowHidden( i, !match );
}
Chris
  • 17,119
  • 5
  • 57
  • 60
  • Can you please give me some sample code so that i may understand your approach.Thanks in advance – john Jul 22 '11 at 04:07
  • Off the top of my head it might look something like this: – Chris Jul 22 '11 at 04:37
  • 4
    Or, we can simply use `QTableWidget.findItems(criteria, Qt.MatchContains)` which will return list of cell matching `criteria` – swdev Jun 05 '14 at 20:45
27

I HIGHLY recommend going about this in the following way! This is how it is meant to be done in Qt.

Look at the tutorial on Qt Model/View Programming. The problem is that QTableWidget is a convenience class that hides the Model/View stuff for you. In your case, you can't (or shouldn't) ignore the Model/View structure Qt provides.

What you will need to do:

  1. Use a QTableView instead of a QTableWidget.
  2. Subclass QAbstractItemModel and implement data() (for reading), and all the other functions you need from the documentation. This is the trickiest part, but refer to the above link for a walkthrough of how to do this.
  3. Create a QSortFilterProxyModel and setModel() of the QTableView to it.
  4. setSourceModel() of your QSortFilterProxyModel to your subclassed model.
  5. Set the string you want to filter on using setFilterFixedString() or setFilterRegExp() in your QSortFilterProxyModel

Let me know if this helps. This is far more professional, and in the long run, elegant, than iterating through all the elements in your table.

Dave Chandler
  • 651
  • 6
  • 17
kevlar1818
  • 3,055
  • 6
  • 29
  • 43
  • 1
    I STRONGLY support that ;) Things tend to start simple, and at some point you are not only hitting the barriers with other "brute force" methods but probably have lots more work to re-implement a model/view approach. In other words: If something is an overkill (like written above) can't be judged in the beginning... – t_3 Jun 15 '15 at 16:23