[SOLVED] How to search item's on a listwiget from their name, and remove the ones that doesnt fit?



  • So i have a listwidget and a lineedit that when the text is changed, if the text doesn't fit an item from the listwidget remove that item and restore it if it fits after.. What i want to do is a search function. So first idea is something like this:

    @search_list.clear();
    search_list=ui->listWidget->findItems(ui->lineEdit->text(), Qt::MatchContains);
    if(search_list.count()){
    select_this_item=0;
    search_list.at(select_this_item)->setSelected(true);
    select_this_item++;
    ui->listWidget->scrollToItem(ui->listWidget->selectedItems().at(0));
    ui->listWidget->setCurrentItem(ui->listWidget->selectedItems().at(0));@

    ( i know it doesn't do what i want, i was just testing, i don't know what to do to remove and restore items.. ).. the code above crashes the app when the text changes.. So what exactly should i do? Should i have a qsettings file and search through it or is there any other better solution?



  • Where does it crash? Use a debug build and the debugger of Qt Creator, set a breakpoint at the code of interest and step line by line. On a crash, it shows you a nice stack trace and you can jump to the code lines of interest.

    Your code snippet does not look fishy, so it's unclear what's going wrong here.



  • If I were you, I would replace my QListWidget with a QStandardItemModel (or some other model) + a QListView, and then use a QSortFilterProxyModel between these two to do the kind of filtering you are trying to do manuall. That should be much easier.



  • [quote author="Andre" date="1322461845"]If I were you, I would replace my QListWidget with a QStandardItemModel (or some other model) + a QListView, and then use a QSortFilterProxyModel between these two to do the kind of filtering you are trying to do manuall. That should be much easier.[/quote]

    Can't that be done at a listwidget itself?



  • [quote author="Volker" date="1322434093"]Where does it crash? Use a debug build and the debugger of Qt Creator, set a breakpoint at the code of interest and step line by line. On a crash, it shows you a nice stack trace and you can jump to the code lines of interest.

    Your code snippet does not look fishy, so it's unclear what's going wrong here.[/quote]
    I get somethink like that:
    @
    The inferior stopped because it received a signal from the Operating System.

    Signal name :
    SIGSEGV
    Signal meaning :
    Segmentation fault@



  • [quote author="Leon" date="1322485073"]
    [quote author="Andre" date="1322461845"]If I were you, I would replace my QListWidget with a QStandardItemModel (or some other model) + a QListView, and then use a QSortFilterProxyModel between these two to do the kind of filtering you are trying to do manuall. That should be much easier.[/quote]

    Can't that be done at a listwidget itself?
    [/quote]
    No, not really. Not without jumping through hoops, anyway. It will be much simpler to do this using a separate model and view. Note that the API of QStandardItemModel is very similar to that of QListWidget, so you won't have many troubles adjusting your code to it.



  • [quote author="Leon" date="1322485300"]
    I get somethink like that:
    @
    The inferior stopped because it received a signal from the Operating System.

    Signal name :
    SIGSEGV
    Signal meaning :
    Segmentation fault@

    [/quote]

    This means: fire up your debugger, and study the last couple of lines of the stack trace that refer to your own code.



  • I think i will go with the QSettings idea. Just clear items in listwidget and add the ones that match. That's cause i am not familiar with either QStandardItemModel, QListView or QSortFilterProxyModel and i could never understand a class from it's class reference.
    You think that would be a bad way of doing this? The item's will be about 1000+



  • QSettings is meant for persisting data inbetween subsequent runs of your program. It's a perfect means for storing user settings, size and position of your windows, etc. It can be abused for other purpuses, of course.

    So, you did not tell us whether your list is built from scratch on ever program run or not. If it is, just store it in a QStringList or something similar. If its more or less immutable, writing to a file using [[QDataStream]] seems to be a better alternative.

    But please, do yourself a favor and use a [[Doc:QSortFilterProxyModel]] together with a [[Doc:QListView]] and a [[Doc:QStandardItemModel]] the last two work almost the same way as a list widget. The QSortFilterProxyModel contains everything you need in regard to the filtering.

    The basic architecture is like this:

    • the standard item model is what you work with, much like with the list widget
    • the sort filter model does all the filtering for you, set your standard item model as the source model for the filter
    • the list view displays your data, you will most probably do not have to deal with it much. Set the sort filter model as the model for the view


  • K i started trying it. So at my ui i have a lineedit and a listview..
    At my .cpp file i have :

    @QStringList list;
    list << "item1" << "item2" << "item3" << "item4" << "item5";
    QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this);
    proxyModel->setSourceModel(new QStringListModel(list));
    ui->listView->setModel(proxyModel);@

    What should i do so as the items that doesn't match be removed and restored like i said?
    somethink like setFilter(ui->lineedit->text)



  • The items are not removed. They're just not displayed.



  • [quote author="Leon" date="1322521126"]
    What should i do so as the items that doesn't match be removed and restored like i said?
    somethink like setFilter(ui->lineedit->text)[/quote]
    Yes, something like that.

    You could make a slot like this:
    @
    void updateListFilter(const QString& filterString)
    {
    proxyModel->setFilterWildcard(QString("%1").arg(filterString);
    }
    @

    and then somewhere call
    @
    connect (ui->lineEdit, SIGNAL(textChanged(QString)), this, SLOT(updateListFilter(QString)));
    @



  • Sorry for late answer, i didn't have my laptop.
    Thanks a lot Andre and Volker! It works :)

    [quote author="Andre" date="1322549362"]
    [quote author="Leon" date="1322521126"]
    What should i do so as the items that doesn't match be removed and restored like i said?
    somethink like setFilter(ui->lineedit->text)[/quote]
    Yes, something like that.

    You could make a slot like this:
    @
    void updateListFilter(const QString& filterString)
    {
    proxyModel->setFilterWildcard(QString("%1").arg(filterString);
    }
    @

    and then somewhere call
    @
    connect (ui->lineEdit, SIGNAL(textChanged(QString)), this, SLOT(updateListFilter(QString)));
    @

    [/quote]


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.