Adan RH
Adan RH

Reputation: 65

QTableview Search

I am doing a search engine for a QTableview, and this is what i have until now:

  void Inventory::on_Search_clicked(){

    QModelIndexList matchList = ui->tableView->model()->match(ui->tableView->model()->index(0,0), Qt::EditRole, ui->lineEdit->text(), -1,  Qt::MatchFlags(Qt::MatchContains|Qt::MatchWrap));

    if(matchList.count()>=1){

            ui->tableView->setCurrentIndex(matchList.first());
            ui->tableView->scrollTo(matchList.first()); 
            }

    QSound::play("/home/adan/Groostore/Resources/Sounds/Update.wav");
}

It works as required, but i want to add another functionality:

This code search for specific matches with a QLineedit and it selects and scrolls to the first value of the QModelindexList, but, if i click a second time searching the same text on the QLineedit, i would like the selection to scroll to the 2 item on the QModelindexList, i have tried many things with no luck, i hope you can help on this, Thanks!

Upvotes: 1

Views: 923

Answers (1)

eyllanesc
eyllanesc

Reputation: 243897

You have to use an index that indicates the number of occurrence that must be selected:

#include <QtWidgets>

class Widget: public QWidget{
public:
    Widget(QWidget *parent=nullptr):QWidget(parent){
        lineedit = new QLineEdit;
        QPushButton *button = new QPushButton("Search");
        view = new QTableView;
        model = new QStandardItemModel;
        view->setModel(model);

        QGridLayout *lay = new QGridLayout(this);
        lay->addWidget(lineedit, 0, 0);
        lay->addWidget(button, 0, 1);
        lay->addWidget(view, 1, 0, 1, 2);

        connect(button, &QPushButton::clicked, this, &Widget::onClicked);
        connect(lineedit, &QLineEdit::textChanged, this, &Widget::onTextChanged);

        // fill model
        const QStringList words = {"stack", "overflow"};
        model->setColumnCount(2);
        for(int i=0; i < 20; i++){
            int p = QRandomGenerator::global()->bounded(words.length());
            model->appendRow(new QStandardItem(words[p]));
        }
    }
    void onClicked(){
        findText(lineedit->text(), ++index, Qt::MatchContains|Qt::MatchWrap);
    }
    void onTextChanged(){
        index = -1;
    }
    void findText(const QString & text, int from, Qt::MatchFlags flags = Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap)){
        if(text.isEmpty())
            return;
        QModelIndexList indexes = model->match(model->index(0,0),
                                               Qt::EditRole,
                                               text,
                                               -1,
                                               flags);
        if(indexes.length() > from){
            QModelIndex ix = indexes.at(from);
            view->setCurrentIndex(ix);
            view->scrollTo(ix);
        }
    }
    int index = -1;
    QStandardItemModel *model;
    QTableView *view;
    QLineEdit *lineedit;
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

Upvotes: 2

Related Questions