Qt实现自动补充功能的QLineEdit

一、非使用QCompleter版
在这里插入图片描述

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

#include <QtGui/QLineEdit>
#include

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

#include <QtGui/QListView>

#include <QtGui/QStringListModel>

#include

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§.x();

int y = mapToGlobal§.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

#include

#include

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.cppblog.com/biao/archive/2009/10/31/99873.html)

二、使用QCompleter版(待更…)