-------------------------------------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 = ); 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() + ;
if (row >= count) {
row = ;
}
QModelIndex index = listView->model()->index(row, );
listView->setCurrentIndex(index); } else if (Qt::Key_Up == key) {
// 按向下方向键时,移动光标选中上一个完成列表中的项
int row = currentIndex.row() - ;
if (row < ) {
row = count - ;
}
QModelIndex index = listView->model()->index(row, );
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() > ) && (!listView->isHidden())) {
return;
} // 如果完整的完成列表中的某个单词包含输入的文本,则加入要显示的完成列表串中
QStringList sl;
foreach(QString word, words) {
if (word.contains(text)) {
sl << word;
}
} model->setStringList(sl);
listView->setModel(model); if (model->rowCount() == ) {
return;
} // Position the text edit
listView->setMinimumWidth(width());
listView->setMaximumWidth(width()); QPoint p(, height());
int x = mapToGlobal(p).x();
int y = mapToGlobal(p).y() + ;
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