qt 自动完成LineEdit

 
 
-------------------------------------CompleteLineEdit.h-------------------------------------
#ifndef COMPLETELINEEDIT_H
#define COMPLETELINEEDIT_H

#include <QtGui/QLineEdit>
#include <QStringList>

class QListView;
class QStringListModel;
class QModelIndex;

class CompleteLineEdit : public QLineEdit {
    Q_OBJECT
public:
    CompleteLineEdit(QStringList words, QWidget *parent = 0);


public slots:
    void setCompleter(const QString &text); // 动态的显示完成列表
    void completeText(const QModelIndex &index); // 点击完成列表中的项,使用此项自动完成输入的单词

protected:
    virtual void keyPressEvent(QKeyEvent *e);
    virtual void focusOutEvent(QFocusEvent *e);

private:
    QStringList words; // 整个完成列表的单词
    QListView *listView; // 完成列表
    QStringListModel *model; // 完成列表的model
};

#endif // COMPLETELINEEDIT_H

-------------------------------------CompleteLineEdit.cpp-------------------------------------
#include "CompleteLineEdit.h"
#include <QKeyEvent>
#include <QtGui/QListView>
#include <QtGui/QStringListModel>
#include <QDebug>

CompleteLineEdit::CompleteLineEdit(QStringList words, QWidget *parent)
    : QLineEdit(parent), words(words) {

    listView = new QListView(this);
    model = new QStringListModel(this);
    listView->setWindowFlags(Qt::ToolTip);

    connect(this, SIGNAL(textChanged(const QString &)), this, SLOT(setCompleter(const QString &)));
    connect(listView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(completeText(const QModelIndex &)));
}

void CompleteLineEdit::focusOutEvent(QFocusEvent *e) {
    //listView->hide();
}

void CompleteLineEdit::keyPressEvent(QKeyEvent *e) {

    if (!listView->isHidden()) {
        int key = e->key();
        int count = listView->model()->rowCount();
        QModelIndex currentIndex = listView->currentIndex();

        if (Qt::Key_Down == key) {
            // 按向下方向键时,移动光标选中下一个完成列表中的项
            int row = currentIndex.row() + 1;
            if (row >= count) {
                row = 0;
            }
            QModelIndex index = listView->model()->index(row, 0);
            listView->setCurrentIndex(index);

        } else if (Qt::Key_Up == key) {
            // 按向下方向键时,移动光标选中上一个完成列表中的项
            int row = currentIndex.row() - 1;
            if (row < 0) {
                row = count - 1;
            }
            QModelIndex index = listView->model()->index(row, 0);
            listView->setCurrentIndex(index);

        } else if (Qt::Key_Escape == key) {
            // 按下Esc键时,隐藏完成列表
            listView->hide();
        } else if (Qt::Key_Enter == key || Qt::Key_Return == key) {
            // 按下回车键时,使用完成列表中选中的项,并隐藏完成列表
            if (currentIndex.isValid()) {
                QString text = listView->currentIndex().data().toString();
                setText(text);
            }
            listView->hide();
        } else {
            // 其他情况,隐藏完成列表,并使用QLineEdit的键盘按下事件
            listView->hide();
            QLineEdit::keyPressEvent(e);
        }
    } else {
        QLineEdit::keyPressEvent(e);
    }
}

 

void CompleteLineEdit::setCompleter(const QString &text) {

    if (text.isEmpty()) {
        listView->hide();
        return;
    }

    if ((text.length() > 1) && (!listView->isHidden())) {
        return;
    }

    // 如果完整的完成列表中的某个单词包含输入的文本,则加入要显示的完成列表串中
    QStringList sl;
    foreach(QString word, words) {
        if (word.contains(text)) {
            sl << word;
        }
    }

    model->setStringList(sl);
    listView->setModel(model);

    if (model->rowCount() == 0) {
        return;
    }

    // Position the text edit
    listView->setMinimumWidth(width());
    listView->setMaximumWidth(width());


    QPoint p(0, height());
    int x = mapToGlobal(p).x();
    int y = mapToGlobal(p).y() + 1;
    listView->move(x, y);
    listView->show();
}

 

void CompleteLineEdit::completeText(const QModelIndex &index) {
    QString text = index.data().toString();
    setText(text);
    listView->hide();
}

 
-------------------------------------main.cpp----------------------------------
#include <QtGui/QApplication>
#include "CompleteLineEdit.h"
#include <QtGui>
#include <QCompleter>
#include <QStringList>

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

    QApplication a(argc, argv);
    QStringList sl = QStringList() << "Biao" << "Bin" << "Huang" << "Hua" << "Hello" << "BinBin" << "Hallo";
    QWidget widgetw;
    CompleteLineEdit * edit= new CompleteLineEdit(sl);
    QPushButton *button = new QPushButton("Button");
    QHBoxLayout *layout = new QHBoxLayout();
    layout->addWidget(edit);
    layout->addWidget(button);
    widgetw.setLayout(layout);
    widgetw.show();

    CompleteLineEdit e(sl);
    e.show();
    return a.exec();
}

 

http://www.cnblogs.com/foxhengxing/archive/2010/09/08/1821796.html

原文地址:https://www.cnblogs.com/findumars/p/4982795.html