8

I use QCompleter with QLineEdit, and I want to update QCompleter's model dynamically. i.e. the model's contents are updated according to QLineEdit's text.

1) mdict.h

#include <QtGui/QWidget>

class QLineEdit;
class QCompleter;
class QModelIndex;

class mdict : public QWidget
{
    Q_OBJECT

public:
    mdict(QWidget *parent = 0);
    ~mdict() {}

private slots:
    void on_textChanged(const QString &text);

private:
    QLineEdit *mLineEdit;
    QCompleter *mCompleter;
};

2) mdict.cpp

#include <cassert>
#include <QtGui>
#include "mdict.h"

mdict::mdict(QWidget *parent) : QWidget(parent), mLineEdit(0), mCompleter(0)
{
    mLineEdit = new QLineEdit(this);
    QPushButton *button = new QPushButton(this);
    button->setText("Lookup");

    QHBoxLayout *layout = new QHBoxLayout(this);
    layout->addWidget(mLineEdit);
    layout->addWidget(button);
    setLayout(layout);

    QStringList stringList;
    stringList << "m0" << "m1" << "m2";
    QStringListModel *model = new QStringListModel(stringList);
    mCompleter = new QCompleter(model, this);
    mLineEdit->setCompleter(mCompleter);

    mLineEdit->installEventFilter(this);

    connect(mLineEdit, SIGNAL(textChanged(const QString&)),
            this, SLOT(on_textChanged(const QString&)));
}

void mdict::on_textChanged(const QString &)
{
    QStringListModel *model = (QStringListModel*)(mCompleter->model());
    QStringList stringList;
    stringList << "h0" << "h1" << "h2";
    model->setStringList(stringList);
}

I expect when I input h, it should give me a auto-complete list with h0, h1, and h2 and I could use keyborad to select item. But it doesn't behavior as I expected.

It seems that the model should be set before QLineEdit emits textChanged signal. One way is to reimplement keyPressEvent, but it involves many conditions to get QLineEdit's text.

So, I want to know is there an easy way to update QCompleter's model dynamically?

AAEM
  • 1,837
  • 2
  • 18
  • 26
hu.
  • 131
  • 1
  • 9
  • 1
    I have tried event, it works, but it isn't easy to use for there are so many types of KeyPresses(e.g. Backspace...). In qlinecontrol.cpp, you can see more details. I just want to know could it be done in an easy way? – hu. Dec 18 '09 at 15:28

3 Answers3

5

Oh, I have found the answer:

Use signal textEdited instead of textChanged.

Debuging QT's source code told me the answer.

AAEM
  • 1,837
  • 2
  • 18
  • 26
hu.
  • 131
  • 1
  • 9
  • This has been sort of some help to me too but I still get segmentation fault when I am trying to dig deeper in a directory, please have look at the code on [paste bin](http://pastebin.com/Jxziq8hW).. – Ciasto piekarz Nov 04 '13 at 10:38
2

You can use something like this:

Foo:Foo()
{
    ...
    QLineEdit* le_foodName = new QLineEdit(this);
    QCompleter* foodNameAutoComplete = new QCompleter(this);
    le_foodName->setCompleter(foodNameAutoComplete);

    updateFoodNameAutoCompleteModel();
    ...
}

// We call this function everytime you need to update completer
void Foo::updateFoodNameAutoCompleteModel()
{
    QStringListModel *model;
    model = (QStringListModel*)(foodNameAutoComplete->model());
    if(model==NULL)
        model = new QStringListModel();

    // Get Latest Data for your list here
    QStringList foodList = dataBaseManager->GetLatestFoodNameList() ;

    model->setStringList(foodList);
    foodNameAutoComplete->setModel(model);
}
Emadpres
  • 3,466
  • 2
  • 29
  • 44
1

Use filterMode : Qt::MatchFlags property. This property holds how the filtering is performed. If filterMode is set to Qt::MatchStartsWith, only those entries that start with the typed characters will be displayed. Qt::MatchContains will display the entries that contain the typed characters, and Qt::MatchEndsWith the ones that end with the typed characters. Currently, only these three modes are implemented. Setting filterMode to any other Qt::MatchFlag will issue a warning, and no action will be performed. The default mode is Qt::MatchStartsWith.

This property was introduced in Qt 5.2.

Access functions:

Qt::MatchFlags  filterMode() const
void    setFilterMode(Qt::MatchFlags filterMode)
Aleksey Kontsevich
  • 4,671
  • 4
  • 46
  • 101