Reputation: 65
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
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