LINUX.ORG.RU

Как прикрутить автодополнение в QLinEdit по Tab как в терминале?

 , , ,


0

1

Привет.

Хочется сделать в QLineEdit автодополнение по Tab как терминале, то есть при первом нажатии Tab вызывается список вариантов, а при последующих нажатиях последовательно выбираются варианты из списка. При этом хочется минимально велосипедить и максимально использовать QCompleter.

Вызов самого QCompleter'а по Tab не вызывает трудностей (переопределение keyPressEvent() для QLineEdit и вызов QCompleter::complete()), а вот итерация по возможным вариантам с помощью Tab уже не так проста.

Возможно ли использовать стандартный QCompleter в данном случае или придется городить свой велосипед? Может быть у кого-нибудь уже есть готовые решения для такого случая?

★★★★★

http://harmattan-dev.nokia.com/docs/library/html/qt4/qcompleter.html#iterating-through-completions

Iterating Through Completions

To retrieve a single candidate string, call setCompletionPrefix() with the text that needs to be completed and call currentCompletion(). You can iterate through the list of completions as below:

 for (int i = 0; completer->setCurrentRow(i); i++)
     qDebug() << completer->currentCompletion() << " is match number " << i;

completionCount() returns the total number of completions for the current prefix. completionCount() should be avoided when possible, since it requires a scan of the entire model.

anonymous
()

а вот итерация по возможным вариантам с помощью Tab уже не так проста.

А в чем сложность? Если предыдущая нажатая клавиша была Tab и снова нажали Tab значит надо дать другое автодополнение. Нет?

no-such-file ★★★★★
()

И еще, так ли вам нужен QLineEdit? Может лучше взять QComboBox, заполнить его вариантами и установить editable?

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

значит надо дать другое автодополнение.

В этом вся и проблема. Даже если изменить текущую строку в модели как писал аноним это никак не отразится в интерфейсе. Стандартные кейбиндинги для выбора текущего автодополнения захардкожены в самом QLineEdit и добавить свои собственные похоже нет никакой возможности. Буду рад если я ошибаюсь.

fat_angel ★★★★★
() автор топика
Ответ на: комментарий от no-such-file

Может лучше взять QComboBox

А какая разница? QCompleter для всех одинаковый. И что-то мне подсказывает, что для нормальной реализации необходимого поведения наиболее простым решением станет свой собственный completer.

fat_angel ★★★★★
() автор топика
Ответ на: комментарий от fat_angel

QCompleter для всех одинаковый

Я имел в виду, что все варианты заносятся в комбобокс, а дальше все происходит автоматически, без QCompleter

no-such-file ★★★★★
()
Ответ на: комментарий от fat_angel

это никак не отразится в интерфейсе

Я думаю, что изменения в интефейсе можно сделать руками.

no-such-file ★★★★★
()
Ответ на: комментарий от fat_angel

Стандартные кейбиндинги для выбора текущего автодополнения захардкожены

Теперь объясни: если есть стандартные биндинги - зачем делать нестандартные? Чтобы разнообразить жизнь пользователю, который задолбается угадывать куда ты повесил обработку автокомплита? Да он даже никогда не узнает о существовании автокомплита если не попробует в другое поле перейти с клавиатуры, а не как обычно посредством клика мышкой. Честный человек на твоём месте сам выдрал бы себе руки за такое.

anonymous
()
Ответ на: комментарий от fat_angel

ты серьезно?

#include <QApplication>

#include <QCompleter>
#include <QLineEdit>
#include <QKeyEvent>

class LineEdit: public QLineEdit
{
public:
    LineEdit(QStringList list, QWidget* parent = 0):
        QLineEdit(parent)
    {
        completer = new QCompleter(list);
        index = 0;
    }

protected:
    void keyPressEvent(QKeyEvent *event)
    {
        if(event->key()==Qt::Key_Tab)
        {
            if((!nextCompleter())&&(!nextCompleter()))
                return;
            setText(completer->currentCompletion());
            return;
        }
        QLineEdit::keyPressEvent(event);
        completer->setCompletionPrefix(text());
        index = 0;
    }

private:
    bool nextCompleter()
    {
        if(completer->setCurrentRow(index++)) return true;
        index = 0;
        return false;
    }
private:
    QCompleter* completer;
    int index;
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QLineEdit* line = new LineEdit(QStringList()<<"qwe"<<"qwr"<<"qwt");
    line->show();
    
    return a.exec();
}

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.