feverzsj
feverzsj

Reputation: 179

change QCompleter result in QLineEdit

The QLineEdit is for entering post code. User may also input city name, while QCompleter will display a list of names for user to select. The problem is, on selecting the name in completer, how could the post code be put in the QLineEdit? I tried to connect QCompleter::activated(QModelIndex) to slot that change the QLineEdit text to post code. But later the text was again set to city name by QLineEdit.

Upvotes: 0

Views: 2773

Answers (1)

hank
hank

Reputation: 9853

Sorry, my previous answer was not correct, so I've edited it.

As the documentation says:

QString QCompleter::pathFromIndex ( const QModelIndex & index ) const [virtual]

Returns the path for the given index. The completer object uses this to obtain the completion text from the underlying model. The default implementation returns the edit role of the item for list models. It returns the absolute file path if the model is a QDirModel.

I've got what you need by subclassing QCompleter and reimplementing pathFromIndex:

class CodeCompleter : public QCompleter
{
    Q_OBJECT
public:
    explicit CodeCompleter(QObject *parent = 0);
    
    static const int CompleteRole;

    QString pathFromIndex(const QModelIndex &index) const;
};

const int CodeCompleter::CompleteRole = Qt::UserRole + 1;

CodeCompleter::CodeCompleter(QObject *parent) :
    QCompleter(parent)
{

}

QString
CodeCompleter::pathFromIndex(const QModelIndex &index) const
{
    QMap<int, QVariant> data = model()->itemData(index);
    QString code = data.value(CompleteRole).toString();
    return code;
}

And you can use it like this:

QStringList cities;
    cities << "Moscow" << "London" << "Las Vegas" << "New York";

    QStandardItemModel *model = new QStandardItemModel;
    for (int i = 0; i < cities.count(); ++i)
    {
        QString city = cities.at(i);
        QString code = city.at(0) + QString::number(city.length());///< just an example

        QStandardItem *item = new QStandardItem;
        item->setText(city);
        item->setData(code, CodeCompleter::CompleteRole);

        model->appendRow(item);
    }

    QLineEdit *lineEdit = new QLineEdit(this);

    CodeCompleter *completer = new CodeCompleter(this);
    completer->setModel(model);
    completer->setCaseSensitivity(Qt::CaseInsensitive);
    lineEdit->setCompleter(completer);

Upvotes: 2

Related Questions