自动完成的QLineEdit(非使用QCompleter版)

来源:http://blog.csdn.net/starcloud_zxt/article/details/5186489

另一篇 http://hi.baidu.com/magictour/item/4be047cdd019482e46d5c0f8

自动完成的QLineEdit(非使用QCompleter版)_第1张图片
-------------------------------------CompleteLineEdit.h-------------------------------------

[c-sharp]  view plain copy
  1. #ifndef COMPLETELINEEDIT_H  
  2. #define COMPLETELINEEDIT_H  
  3.  
  4. #include <QtGui/QLineEdit>  
  5. #include <QStringList>  
  6.   
  7. class QListView;  
  8. class QStringListModel;  
  9. class QModelIndex;  
  10.   
  11. class CompleteLineEdit : public QLineEdit {  
  12.   
  13.     Q_OBJECT  
  14. public:  
  15.     CompleteLineEdit(QStringList words, QWidget *parent = 0);  
  16.   
  17. public slots:  
  18.     void setCompleter(const QString &text); // 动态的显示完成列表  
  19.     void completeText(const QModelIndex &index); // 点击完成列表中的项,使用此项自动完成输入的单词  
  20.   
  21. protected:  
  22.     virtual void keyPressEvent(QKeyEvent *e);  
  23.     virtual void focusOutEvent(QFocusEvent *e);  
  24.   
  25. private:  
  26.    QStringList words; // 整个完成列表的单词  
  27.     QListView *listView; // 完成列表  
  28.     QStringListModel *model; // 完成列表的model  
  29.   
  30. };  
  31.  
  32. #endif // COMPLETELINEEDIT_H  


-------------------------------------CompleteLineEdit.cpp-------------------------------------

[c-sharp]  view plain copy
  1. #include "CompleteLineEdit.h"  
  2. #include <QKeyEvent>  
  3. #include <QtGui/QListView>  
  4. #include <QtGui/QStringListModel>  
  5. #include <QDebug>  
  6.   
  7. CompleteLineEdit::CompleteLineEdit(QStringList words, QWidget *parent)  
  8.     : QLineEdit(parent), words(words) {  
  9.     listView = new QListView(this);  
  10.     model = new QStringListModel(this);  
  11.     listView->setWindowFlags(Qt::ToolTip);  
  12.   
  13.     connect(this, SIGNAL(textChanged(const QString &)), this, SLOT(setCompleter(const QString &)));  
  14.   
  15.     connect(listView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(completeText(const QModelIndex &)));  
  16. }  
  17.   
  18. void CompleteLineEdit::focusOutEvent(QFocusEvent *e) {  
  19.     //listView->hide();  
  20. }  
  21.   
  22. void CompleteLineEdit::keyPressEvent(QKeyEvent *e) {  
  23.     if (!listView->isHidden()) {  
  24.         int key = e->key();  
  25.         int count = listView->model()->rowCount();  
  26.         QModelIndex currentIndex = listView->currentIndex();  
  27.         if (Qt::Key_Down == key) {  
  28.             // 按向下方向键时,移动光标选中下一个完成列表中的项  
  29.             int row = currentIndex.row() + 1;  
  30.             if (row >= count) {  
  31.                 row = 0;  
  32.             }  
  33.             QModelIndex index = listView->model()->index(row, 0);  
  34.             listView->setCurrentIndex(index);  
  35.         } else if (Qt::Key_Up == key) {  
  36.             // 按向下方向键时,移动光标选中上一个完成列表中的项  
  37.             int row = currentIndex.row() - 1;  
  38.             if (row < 0) {  
  39.                 row = count - 1;  
  40.             }  
  41.             QModelIndex index = listView->model()->index(row, 0);  
  42.             listView->setCurrentIndex(index);  
  43.         } else if (Qt::Key_Escape == key) {  
  44.             // 按下Esc键时,隐藏完成列表  
  45.             listView->hide();  
  46.         } else if (Qt::Key_Enter == key || Qt::Key_Return == key) {  
  47.             // 按下回车键时,使用完成列表中选中的项,并隐藏完成列表  
  48.             if (currentIndex.isValid()) {  
  49.                 QString text = listView->currentIndex().data().toString();  
  50.                 setText(text);  
  51.             }  
  52.             listView->hide();  
  53.         } else {  
  54.             // 其他情况,隐藏完成列表,并使用QLineEdit的键盘按下事件  
  55.             listView->hide();  
  56.             QLineEdit::keyPressEvent(e);  
  57.         }  
  58.     } else {  
  59.         QLineEdit::keyPressEvent(e);  
  60.     }  
  61. }  
  62.   
  63. void CompleteLineEdit::setCompleter(const QString &text) {  
  64.     if (text.isEmpty()) {  
  65.         listView->hide();  
  66.         return;  
  67.     }  
  68.     if ((text.length() > 1) && (!listView->isHidden())) {  
  69.         return;  
  70.     }  
  71.     // 如果完整的完成列表中的某个单词包含输入的文本,则加入要显示的完成列表串中  
  72.     QStringList sl;  
  73.     foreach(QString word, words) {  
  74.         if (word.contains(text)) {  
  75.             sl << word;  
  76.         }  
  77.     }  
  78.     model->setStringList(sl);  
  79.     listView->setModel(model);  
  80.     if (model->rowCount() == 0) {  
  81.         return;  
  82.     }  
  83.     // Position the text edit  
  84.     listView->setMinimumWidth(width());  
  85.     listView->setMaximumWidth(width());  
  86.     QPoint p(0, height());  
  87.     int x = mapToGlobal(p).x();  
  88.     int y = mapToGlobal(p).y() + 1;  
  89.     listView->move(x, y);  
  90.     listView->show();  
  91.   
  92. }  
  93.   
  94. void CompleteLineEdit::completeText(const QModelIndex &index) {  
  95.     QString text = index.data().toString();  
  96.     setText(text);  
  97.     listView->hide();  
  98. }  


-------------------------------------main.cpp----------------------------------

[c-sharp]  view plain copy
  1. #include <QtGui/QApplication>  
  2. #include "CompleteLineEdit.h"  
  3. #include <QtGui>  
  4. #include <QCompleter>  
  5. #include <QStringList>  
  6.   
  7. int main(int argc, char *argv[]) {  
  8.     QApplication a(argc, argv);  
  9.     QStringList sl = QStringList() << "Biao" << "Bin" << "Huang" << "Hua" << "Hello" << "BinBin" << "Hallo";  
  10.     QWidget widgetw;  
  11.     CompleteLineEdit * edit= new CompleteLineEdit(sl);  
  12.     QPushButton *button = new QPushButton("Button");  
  13.     QHBoxLayout *layout = new QHBoxLayout();  
  14.     layout->addWidget(edit);  
  15.     layout->addWidget(button);  
  16.     widgetw.setLayout(layout);  
  17.     widgetw.show();  
  18.     CompleteLineEdit e(sl);  
  19.     e.show();  
  20.     return a.exec();  
  21. }  

你可能感兴趣的:(自动完成的QLineEdit(非使用QCompleter版))