Page 1 of 2 12 LastLast
Results 1 to 20 of 21

Thread: Searching in QListView

  1. #1
    Join Date
    Feb 2006
    Posts
    91
    Thanks
    4
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Searching in QListView

    I just made my transition to Qt 4.3. Some of the features that I have seen are great, however, it's quite a jump from Qt 3.3 which I used to code in before.
    Could anyone suggest me how could I search the QListView which has the model as QStringListModel for a regexp.
    Actually, I want to produce the effect like that of the Qt Assistant side bar where you can search. Moreover I need to scroll in the listview to the item which I think I can achive with teh scrollTo() function.

    Any help on using findchildren(QRegexp) to find the items in the QListView will be appreciated.
    BTW, MVC is great
    Humans make mistake because there is really NO patch for HUMAN STUPIDITY

  2. #2
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Searching in QListView

    Quote Originally Posted by ct View Post
    Actually, I want to produce the effect like that of the Qt Assistant side bar where you can search.
    Then why don't you try to have a look at Qt Assistant sources? AFAIK the simplest way to do this, as you're using a real model and not an item-based stuff, is to rely on a QSortFilterProxyModel.
    Current Qt projects : QCodeEdit, RotiDeCode

  3. #3
    Join Date
    Mar 2006
    Location
    The Netherlands
    Posts
    300
    Thanks
    9
    Thanked 29 Times in 29 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Searching in QListView

    Like FMC said, you want QSortFilterProxyModel. Read the docs.

    I don't think there's anything very smart going on there. It just walks through the list, filtering out those items that don't match.
    "The strength of a civilization is not measured by its ability to wage wars, but rather by its ability to prevent them." - Gene Roddenberry

  4. #4
    Join Date
    Feb 2006
    Posts
    91
    Thanks
    4
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Searching in QListView

    I don't think there's anything very smart going on there. It just walks through the list, filtering out those items that don't match.
    I did try the QSortFilterProxyModel just now. It is a bit slow though. I have a huge dictionary which needs to be searched. Amazingly though Qt Assistant's search is quite fast however I guess it is using some sort of searching algorithm. I wish there was an easier and efficient way.
    Humans make mistake because there is really NO patch for HUMAN STUPIDITY

  5. #5
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Searching in QListView

    Quote Originally Posted by ct View Post
    I did try the QSortFilterProxyModel just now. It is a bit slow though. I have a huge dictionary which needs to be searched. Amazingly though Qt Assistant's search is quite fast however I guess it is using some sort of searching algorithm. I wish there was an easier and efficient way.
    What is the order of the items in the dictionary?
    If they are already sorted, then you can write your own model and use a faster algorithm for sorted sets, like binary search.

    Regards

  6. #6
    Join Date
    Mar 2006
    Location
    The Netherlands
    Posts
    300
    Thanks
    9
    Thanked 29 Times in 29 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Searching in QListView

    But if you want to search for regex-patterns, binary search, which searches for prefixes only (or at least predetermined substrings), won't work.
    "The strength of a civilization is not measured by its ability to wage wars, but rather by its ability to prevent them." - Gene Roddenberry

  7. #7
    Join Date
    Feb 2006
    Posts
    91
    Thanks
    4
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Searching in QListView

    Qt Code:
    1. QList<QString>::iterator i = qBinaryFind(dictionaryList.begin(), dictionaryList.end(),text);
    2. listView->scrollTo(i,1);
    To copy to clipboard, switch view to plain text mode 

    I need to do something like this. The dictionaryList is a QStringList . It says in the manual that i is the position. I would like to move to the listView where it is the first match. How do I convert an iterator to QModelIndex ?

    Also how do I create a List of items that matches with all the values in QStringList so that I could make a new StringList and set the proxy model to it and all the matched Strings are shown .
    Humans make mistake because there is really NO patch for HUMAN STUPIDITY

  8. #8
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Searching in QListView

    Quote Originally Posted by ct View Post
    Qt Code:
    1. QList<QString>::iterator i = qBinaryFind(dictionaryList.begin(), dictionaryList.end(),text);
    2. listView->scrollTo(i,1);
    To copy to clipboard, switch view to plain text mode 
    I need to do something like this. The dictionaryList is a QStringList . It says in the manual that i is the position. I would like to move to the listView where it is the first match. How do I convert an iterator to QModelIndex ?
    .
    Like this:
    Qt Code:
    1. int index = dictionaryList.indexOf( *i );
    2. QModelIndex modelIndex(index, 1);
    To copy to clipboard, switch view to plain text mode 

    Regards

  9. #9
    Join Date
    Feb 2006
    Posts
    91
    Thanks
    4
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Searching in QListView

    Qt Code:
    1. error: no matching function for call to `QModelIndex::QModelIndex(int&, int)'
    To copy to clipboard, switch view to plain text mode 
    Humans make mistake because there is really NO patch for HUMAN STUPIDITY

  10. #10
    Join Date
    Feb 2006
    Posts
    91
    Thanks
    4
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Searching in QListView

    I tried to look at the Assistant Code, and I see something .

    Qt Code:
    1. class IndexListModel;
    To copy to clipboard, switch view to plain text mode 

    This model is doing the filter job. However, I can't find it's declaration besides this small forward declaration. Is it that the uic will generate this IndexListModel ? Also I notice that the listview is named indexList. Is is sometype of auto generation inside Qt or am I missing something totally ?

    BTW, I am referring to following code in Qt Assistant
    ---------- HELPDIALOG.H
    [45]class IndexListModel;
    [142] IndexListModel *indexModel;
    Humans make mistake because there is really NO patch for HUMAN STUPIDITY

  11. #11
    Join Date
    Feb 2006
    Posts
    91
    Thanks
    4
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Searching in QListView

    Currently I am connecting the textChanged(QString)SIGNAL of QLineEdit to the setFilterFixedString(QString) slot of the QSortFilterProxyModel as suggested by the manual but I need something faster ... anyone ???
    Humans make mistake because there is really NO patch for HUMAN STUPIDITY

  12. #12
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Searching in QListView

    One simple trick to make it feel slightly faster is to emit a custom signal, let's say textDelayedChange(QString), after a certain delay when no changes have been made. Every change resets the timer and once it reaches the predefined delay, the signal is emitted. This way entering a string of 10 chars does not trigger 10 re-filterings but one (provided that the string is entered in a row and no delay exceeds in between strokes).

    PS. As far as I remember, Qt Assistant performs search on a custom indexed dictionary.
    J-P Nurmi

  13. #13
    Join Date
    Feb 2006
    Posts
    91
    Thanks
    4
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Searching in QListView



    yes, that is just great. It's the each textChange() signal that is causing the trouble.
    Qt Code:
    1. ...
    2. connect(lineEdit,SIGNAL(textChanged(QString)),this,delayChange(QString)));
    3. connect(this,SIGNAL(textChangeDelayed(QString)),proxyModel,SLOT(setFilterFixedString(QString)));
    4. ....
    5.  
    6. void delayChange(QString)
    7. {
    8. //reset timer;
    9. timer = 0;
    10. while(timer < 9999)
    11. timer++;
    12.  
    13. if(timer > 9999)
    14. emit textChangeDelayed(String);
    15.  
    16. }
    To copy to clipboard, switch view to plain text mode 

    Is this what you meant ? I am a bit confused about how this type of slots ar handled though. Do they all run in thread ? Wont' all the slots emit the textChangeDelayed() eventually ? How do you cause the delay.

    PS. As far as I remember, Qt Assistant performs search on a custom indexed dictionary.
    I was thinking about it too. I have around 22,000 words so eventually sorting is slow too. I have to keep it in a indexed file. So I might as well do something with the index of each word starting from a particular alphabet at the time of loading.
    But, I like this delay thing, it is less work
    Humans make mistake because there is really NO patch for HUMAN STUPIDITY

  14. #14
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Searching in QListView

    You can't block the event loop of a GUI application with a busy loop. You should do it more or less like this:
    Qt Code:
    1. QTime delay;
    2. static const int DELAY = 200; // ms
    3. ...
    4. connect(lineEdit,SIGNAL(textChanged(QString)),this,delayChange()));
    5. connect(this,SIGNAL(textChangeDelayed(QString)),proxyModel,SLOT(setFilterFixedString(QString)));
    6. ....
    7.  
    8. void delayChange()
    9. {
    10. delay.start();
    11. QTimer::singleShot(DELAY, this, SLOT(informChange()));
    12. }
    13.  
    14. void informChange()
    15. {
    16. if (delay.elapsed() >= DELAY)
    17. emit textChangeDelayed(lineEdit->text());
    18. else
    19. QTimer::singleShot(DELAY - delay.elapsed(), this, SLOT(informChange()));
    20. }
    To copy to clipboard, switch view to plain text mode 
    J-P Nurmi

  15. The following user says thank you to jpn for this useful post:

    ct (27th July 2007)

  16. #15
    Join Date
    Mar 2006
    Location
    The Netherlands
    Posts
    300
    Thanks
    9
    Thanked 29 Times in 29 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Searching in QListView

    I suggest the following code. Might be a little cleaner (assuming QLineEdit subclass):

    Qt Code:
    1. class DelayLineEdit : public QLineEdit {
    2. Q_OBJECT
    3.  
    4. public:
    5. DelayLineEdit(QWidget * parent = 0) : QLineEdit(parent) {
    6. _delay = new QTimer(this);
    7. _delay->setInterval(200); // ms
    8. _delay->setSingleShot(true);
    9. connect(this, SIGNAL(textChanged(QString)), _delay, SLOT(start()));
    10. connect(_delay, SIGNAL(timeout()), this, SLOT(informChange()));
    11. }
    12.  
    13. private slots:
    14. void informChange() {
    15. emit textChangeDelayed(text());
    16. }
    17.  
    18. signals:
    19. void textChangeDelayed(QString);
    20.  
    21. private:
    22. QTimer* _delay;
    23. }
    To copy to clipboard, switch view to plain text mode 

    Of course, the informChange() slot is only necessary if you really want to add the new text to the signal. If an empty signal is enough, you can put that signal directly in the second connect of the constructor (signal chaining).

    Edit: This code has now been tested. (Though I've changed some details from the code above.) I've uploaded an example project, ready to compile. Feel free to use the code.
    Attached Files Attached Files
    Last edited by Michiel; 26th July 2007 at 16:13. Reason: Added demonstration project
    "The strength of a civilization is not measured by its ability to wage wars, but rather by its ability to prevent them." - Gene Roddenberry

  17. The following user says thank you to Michiel for this useful post:

    ct (27th July 2007)

  18. #16
    Join Date
    Feb 2006
    Posts
    91
    Thanks
    4
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Searching in QListView

    Thanks, it seems to quicken things up. I guess I will go dig up the manual more..there are so many new things in Qt 4.3.0.
    Thanks again jpn and Michiel.
    Humans make mistake because there is really NO patch for HUMAN STUPIDITY

  19. #17
    sharrychrist Guest

    Default Re: Searching in QListView

    Hi, this post is very informative; however I would like some specific information. If someone can help me then please send me a private message. Best Regards,

  20. #18
    Join Date
    Mar 2006
    Location
    The Netherlands
    Posts
    300
    Thanks
    9
    Thanked 29 Times in 29 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Searching in QListView

    Feel free to ask your questions right here. If we communicate by private message, no one else will benefit from it.
    "The strength of a civilization is not measured by its ability to wage wars, but rather by its ability to prevent them." - Gene Roddenberry

  21. #19
    Join Date
    Mar 2006
    Location
    The Netherlands
    Posts
    300
    Thanks
    9
    Thanked 29 Times in 29 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Searching in QListView

    It just occurred to me that a useful macro could be created that does the same thing without the need for subclasses or extra clutter in your code. It would be great if you could do something like this:

    connect(object1, DELAYED_SIGNAL(textChanged(), 200), object2, SLOT(doSomething()));

    The DELAYED_SIGNAL macro is probably possible. But I don't know enough about the internals of the signal/slot system to create it myself.
    "The strength of a civilization is not measured by its ability to wage wars, but rather by its ability to prevent them." - Gene Roddenberry

  22. #20
    Join Date
    Feb 2006
    Posts
    91
    Thanks
    4
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Searching in QListView

    Actually, I used jpn's method ...it worked like a charm without subclassing. Yours is nice too but I was lazy to subclass as I already had all the widgets laid out.
    I am however thinking about using some sort of searching algorithm algorithm..as QListView takes time to load the items..especially when you hit "backspace" and there are no items in the LineEdit and all the items have to be loaded onto QListView. But even then I don't know if it is some other thing that might be causing this.
    May be a PIII with 192mb RAM is not enough
    Humans make mistake because there is really NO patch for HUMAN STUPIDITY

Similar Threads

  1. QListView word wrap
    By serega in forum Qt Programming
    Replies: 17
    Last Post: 30th August 2007, 04:13
  2. QDialog / QListView problem
    By harakiri in forum Qt Programming
    Replies: 1
    Last Post: 10th July 2007, 19:31
  3. Subclass QListView to show two colums in one
    By Mookie in forum Qt Programming
    Replies: 2
    Last Post: 23rd June 2007, 03:12
  4. Replies: 0
    Last Post: 10th November 2006, 14:46
  5. Keeping focus at bottom of QListView
    By jakamph in forum Qt Programming
    Replies: 4
    Last Post: 10th January 2006, 15:45

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.