Search code examples
c++qtqcompleter

How to change the order of a QCompleter popup?


I have created a custom QCompleter class which displays all items in a popup that contain the typed word of a QLineEdit.

Right now all items are ordered alphabetically as you can see here:

enter image description here

I want the popup to display "dab" as the first suggestion if I type in "dab" and then the other items in alphabetical order.

I want this popup order:

  • dab
  • amendable
  • decidable
  • dividable
  • guidable
  • spendable
  • ...

How can i achieve this?

This is the custom QCompleter class I'm using:

Code

class MyCompleter : public QCompleter
{
    Q_OBJECT

public:
    inline MyCompleter(const QStringList& words, QObject * parent) :
            QCompleter(parent), m_list(words), m_model()
    {
        setModel(&m_model);
    }

    // Filter
    inline void update(QString word)
    {
        // Include all items that contain "word".

        QStringList filtered = m_list.filter(word, caseSensitivity());
        m_model.setStringList(filtered);
        m_word = word;
        complete();
    }

    inline QString word()
    {
        return m_word;
    }

private:
    QStringList m_list;
    QStringListModel m_model;
    QString m_word;
};

Solution

  • I did it myself by creating a copy of my m_list and searching it with the startsWith function. I then added the found items to a tempList and filtered the c_m_list as I did in my question. The filtered list also got added to the tempList.

    Now it looks like this:

    popup example

    Code

    class MyCompleter : public QCompleter
    {
        Q_OBJECT
    
    public:
        inline MyCompleter(const QStringList& words, QObject * parent) :
                QCompleter(parent), m_list(words), m_model()
        {
            setModel(&m_model);
        }
    
        inline void update(QString word)
        {
            // Include all items that contain "word".
            int idx(0);
            QStringList tempList;
            QStringList c_m_list(m_list);
    
            while (idx < c_m_list.size())
            {
                if (c_m_list.at(idx).startsWith(word,Qt::CaseInsensitive))
                {
                    tempList.append(c_m_list.takeAt(idx--));
                }
                idx++;
            }
    
            QStringList filtered = c_m_list.filter(word, caseSensitivity());
            c_m_list.sort();
    
            tempList.append(filtered);
    
            m_model.setStringList(tempList);
            m_word = word;
            complete();
        }
    
        inline QString word()
        {
            return m_word;
        }
    
    private:
        QStringList m_list;
        QStringListModel m_model;
        QString m_word;
    };